Skip to content

Commit 000a795

Browse files
authored
Merge branch 'master' into master
2 parents 48e4efe + a4b9f17 commit 000a795

28 files changed

+706
-128
lines changed

src/core/Browser.js

Lines changed: 11 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { isFunction } from './util/common';
22
import { IS_NODE } from './util/env';
33

44
let Browser = {};
5-
const maps = {};
5+
// const maps = {};
66

77
function getDevicePixelRatio() {
88
return (window.devicePixelRatio || (window.screen.deviceXDPI / window.screen.logicalXDPI));
@@ -126,11 +126,11 @@ if (!IS_NODE) {
126126
monitorDPRChange: true,
127127
supportsPassive,
128128
proxy,
129-
removeDPRListening: (map) => {
130-
if (map) {
131-
delete maps[map.id];
132-
}
133-
},
129+
// removeDPRListening: (map) => {
130+
// // if (map) {
131+
// // delete maps[map.id];
132+
// // }
133+
// },
134134
checkDevicePixelRatio: () => {
135135
if (typeof window !== 'undefined' && Browser.monitorDPRChange) {
136136
const devicePixelRatio = getDevicePixelRatio();
@@ -142,55 +142,11 @@ if (!IS_NODE) {
142142
}
143143
return false;
144144
},
145-
addDPRListening: (map) => {
146-
if (map) {
147-
maps[map.id] = map;
148-
}
149-
}
145+
// addDPRListening: (map) => {
146+
// // if (map) {
147+
// // maps[map.id] = map;
148+
// // }
149+
// }
150150
};
151-
//monitor devicePixelRatio change
152-
if (typeof window !== 'undefined' && window.matchMedia) {
153-
for (let i = 1; i < 500; i++) {
154-
const dpi = (i * 0.01).toFixed(2);
155-
const screen = window.matchMedia(`screen and (resolution: ${dpi}dppx)`);
156-
if (screen) {
157-
if (screen.addEventListener) {
158-
screen.addEventListener('change', Browser.checkDevicePixelRatio);
159-
} else if (screen.addListener) {
160-
screen.addListener(Browser.checkDevicePixelRatio);
161-
}
162-
}
163-
}
164-
165-
}
166-
167-
if (Browser.devicePixelRatio) {
168-
let tempDPI = Browser.devicePixelRatio;
169-
Object.defineProperty(Browser, 'devicePixelRatio', {
170-
get: () => {
171-
return tempDPI;
172-
},
173-
set: (value) => {
174-
if (value === tempDPI) {
175-
return;
176-
}
177-
//when devicePixelRatio change force resize all layers
178-
tempDPI = value;
179-
if (!Browser.monitorDPRChange) {
180-
return;
181-
}
182-
for (const mapId in maps) {
183-
const map = maps[mapId];
184-
if (!map || !map.options || map.options['devicePixelRatio'] || !map.checkSize || !map.getRenderer) {
185-
continue;
186-
}
187-
const renderer = map.getRenderer();
188-
if (renderer) {
189-
map.checkSize(true);
190-
}
191-
}
192-
}
193-
});
194-
}
195151
}
196152
export default Browser;

src/core/GlobalEvent.js

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
import Eventable from './Eventable';
2+
import Browser from './Browser';
3+
import { addDomEvent } from './util/dom';
4+
5+
class Base {
6+
7+
}
8+
9+
class GlobalEventable extends Eventable(Base) {
10+
11+
}
12+
13+
// this is global event bus for doc state change
14+
// such as : devicePixelRatio ,visibilitychange,... etc
15+
16+
export const GlobalEvent = new GlobalEventable();
17+
18+
export const EVENT_DPR_CHANGE = 'dprchange';
19+
export const EVENT_DOC_VISIBILITY_CHANGE = 'docvisibilitychange';
20+
export const EVENT_DOC_DRAGSTART = 'dragstart';
21+
export const EVENT_DOC_DRAGEND = 'dragend';
22+
23+
24+
//monitor devicePixelRatio change
25+
if (typeof window !== 'undefined' && window.matchMedia) {
26+
for (let i = 1; i < 500; i++) {
27+
const dpi = (i * 0.01).toFixed(2);
28+
const screen = window.matchMedia(`screen and (resolution: ${dpi}dppx)`);
29+
if (screen) {
30+
if (screen.addEventListener) {
31+
screen.addEventListener('change', Browser.checkDevicePixelRatio);
32+
} else if (screen.addListener) {
33+
screen.addListener(Browser.checkDevicePixelRatio);
34+
}
35+
}
36+
}
37+
38+
}
39+
40+
if (Browser.devicePixelRatio) {
41+
let tempDPI = Browser.devicePixelRatio;
42+
Object.defineProperty(Browser, 'devicePixelRatio', {
43+
get: () => {
44+
return tempDPI;
45+
},
46+
set: (value) => {
47+
if (value === tempDPI) {
48+
return;
49+
}
50+
//when devicePixelRatio change force resize all layers
51+
tempDPI = value;
52+
if (!Browser.monitorDPRChange) {
53+
return;
54+
}
55+
GlobalEvent.fire(EVENT_DPR_CHANGE, { devicePixelRatio: value });
56+
}
57+
});
58+
}
59+
60+
//monitor document visibilitychange change
61+
if (Browser.webgl && typeof document !== 'undefined') {
62+
addDomEvent(document, 'visibilitychange', () => {
63+
GlobalEvent.fire(EVENT_DOC_VISIBILITY_CHANGE, { visibilityState: document.visibilityState });
64+
});
65+
addDomEvent(document, 'dragstart', () => {
66+
GlobalEvent.fire(EVENT_DOC_DRAGSTART);
67+
});
68+
addDomEvent(document, 'dragend', () => {
69+
GlobalEvent.fire(EVENT_DOC_DRAGEND);
70+
});
71+
}

src/core/util/style.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,9 @@ function parseStops(value, replacer) {
194194
value['default'] = defaultValue.replace(URL_PATTERN, replacer);
195195
}
196196
const stops = value.stops;
197+
if (!stops) {
198+
return value;
199+
}
197200
for (let i = 0; i < stops.length; i++) {
198201
if (!Array.isArray(stops[i])) {
199202
continue;

src/geometry/Ellipse.js

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,12 +88,18 @@ class Ellipse extends CenterMixin(Polygon) {
8888
this.onShapeChanged();
8989
return this;
9090
}
91-
9291
/**
9392
* Gets the shell of the ellipse as a polygon, number of the shell points is decided by [options.numberOfShellPoints]{@link Circle#options}
9493
* @return {Coordinate[]} - shell coordinates
9594
*/
9695
getShell() {
96+
if (this.isRotated()) {
97+
return this.getRotatedShell();
98+
}
99+
return this._getShell();
100+
}
101+
102+
_getShell() {
97103
const measurer = this._getMeasurer(),
98104
center = this.getCoordinates(),
99105
numberOfPoints = this.options['numberOfShellPoints'],
@@ -122,6 +128,11 @@ class Ellipse extends CenterMixin(Polygon) {
122128
return shell;
123129
}
124130

131+
_getPrjShell() {
132+
const shell = super._getPrjShell();
133+
return this._rotatePrjCoordinates(shell);
134+
}
135+
125136
/**
126137
* Ellipse won't have any holes, always returns null
127138
* @return {Object[]} an empty array
@@ -148,6 +159,9 @@ class Ellipse extends CenterMixin(Polygon) {
148159
}
149160

150161
_computePrjExtent() {
162+
if (this.isRotated()) {
163+
return this._computeRotatedPrjExtent();
164+
}
151165
return Circle.prototype._computePrjExtent.apply(this, arguments);
152166
}
153167

src/geometry/Geometry.js

Lines changed: 87 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import Painter from '../renderer/geometry/Painter';
2525
import CollectionPainter from '../renderer/geometry/CollectionPainter';
2626
import SpatialReference from '../map/spatial-reference/SpatialReference';
2727
import { isFunctionDefinition } from '../core/mapbox';
28+
import { getDefaultBBOX, pointsBBOX } from '../core/util/bbox';
2829

2930
const TEMP_POINT0 = new Point(0, 0);
3031
const TEMP_EXTENT = new PointExtent();
@@ -929,6 +930,10 @@ class Geometry extends JSONAble(Eventable(Handlerable(Class))) {
929930
* @returns {Geometry} this
930931
*/
931932
rotate(angle, pivot) {
933+
if (!isNumber(angle)) {
934+
console.error(`angle:${angle} is not number`);
935+
return this;
936+
}
932937
if (this.type === 'GeometryCollection') {
933938
const geometries = this.getGeometries();
934939
geometries.forEach(g => g.rotate(angle, pivot));
@@ -939,12 +944,18 @@ class Geometry extends JSONAble(Eventable(Handlerable(Class))) {
939944
} else {
940945
pivot = new Coordinate(pivot);
941946
}
947+
this._angle = angle;
948+
this._pivot = pivot;
942949
const measurer = this._getMeasurer();
943950
const coordinates = this.getCoordinates();
944951
if (!Array.isArray(coordinates)) {
945-
if (pivot.x !== coordinates.x || pivot.y !== coordinates.y) {
952+
//exclude Rectangle ,Ellipse,Sector by shell judge
953+
if ((pivot.x !== coordinates.x || pivot.y !== coordinates.y) && !this.getShell) {
946954
const c = measurer._rotate(coordinates, pivot, angle);
947955
this.setCoordinates(c);
956+
} else {
957+
//only redraw ,not to change coordinate
958+
this.onPositionChanged();
948959
}
949960
return this;
950961
}
@@ -955,6 +966,65 @@ class Geometry extends JSONAble(Eventable(Handlerable(Class))) {
955966
return this;
956967
}
957968

969+
_rotatePrjCoordinates(coordinates) {
970+
if (!coordinates || this._angle === 0 || !this._pivot) {
971+
return coordinates;
972+
}
973+
const projection = this._getProjection();
974+
if (!projection) {
975+
return coordinates;
976+
}
977+
let offsetAngle = 0;
978+
const isArray = Array.isArray(coordinates);
979+
const coord = isArray ? coordinates : [coordinates];
980+
const rotatePrjCoordinates = [];
981+
let cx, cy;
982+
//sector is special
983+
if (this.getRotateOffsetAngle) {
984+
offsetAngle = this.getRotateOffsetAngle();
985+
const center = coord[coord.length - 1];
986+
cx = center.x;
987+
cy = center.y;
988+
} else {
989+
const bbox = getDefaultBBOX();
990+
//cal all points center
991+
pointsBBOX(coord, bbox);
992+
const [minx, miny, maxx, maxy] = bbox;
993+
cx = (minx + maxx) / 2;
994+
cy = (miny + maxy) / 2;
995+
}
996+
//图形按照自身的几何中心旋转
997+
for (let i = 0, len = coord.length; i < len; i++) {
998+
const c = coord[i];
999+
const { x, y } = c;
1000+
const dx = x - cx, dy = y - cy;
1001+
const r = Math.sqrt(dx * dx + dy * dy);
1002+
const sAngle = getSegmentAngle(cx, cy, x, y);
1003+
const rad = (sAngle - this._angle + offsetAngle) / 180 * Math.PI;
1004+
const rx = Math.cos(rad) * r, ry = Math.sin(rad) * r;
1005+
const rc = new Coordinate(cx + rx, cy + ry);
1006+
rotatePrjCoordinates.push(rc);
1007+
}
1008+
const prjCenter = projection.project(this._pivot);
1009+
const rx = prjCenter.x, ry = prjCenter.y;
1010+
//translate rotate center
1011+
const translateX = cx - rx, translateY = cy - ry;
1012+
//平移到指定的选中中心点
1013+
for (let i = 0, len = rotatePrjCoordinates.length; i < len; i++) {
1014+
const c = rotatePrjCoordinates[i];
1015+
c.x -= translateX;
1016+
c.y -= translateY;
1017+
}
1018+
if (isArray) {
1019+
return rotatePrjCoordinates;
1020+
}
1021+
return rotatePrjCoordinates[0];
1022+
}
1023+
1024+
isRotated() {
1025+
return isNumber(this._angle) && this._pivot;
1026+
}
1027+
9581028
/**
9591029
* Get the connect points for [ConnectorLine]{@link ConnectorLine}
9601030
* @return {Coordinate[]} connect points
@@ -1557,7 +1627,7 @@ function getGeometryCoordinatesAlts(geometry, layerAlt, enableAltitude) {
15571627
coordinatesHasAlt(coordinates, tempAlts);
15581628
if (tempAlts.length) {
15591629
const alts = getCoordinatesAlts(coordinates, layerAlt, enableAltitude);
1560-
if (geometry.getShell) {
1630+
if (geometry.getShell && Array.isArray(alts[0])) {
15611631
return alts[0][0];
15621632
}
15631633
return alts;
@@ -1606,5 +1676,20 @@ function getCoordinatesAlts(coordinates, layerAlt, enableAltitude) {
16061676
}
16071677
}
16081678

1679+
function getSegmentAngle(cx, cy, x, y) {
1680+
if (cx === x) {
1681+
if (y > cy) {
1682+
return -90;
1683+
}
1684+
return 90;
1685+
}
1686+
x -= cx;
1687+
y -= cy;
1688+
//经纬坐标系和屏幕坐标正好相反,经纬度向上递增,而屏幕坐标递减
1689+
y = -y;
1690+
const rad = Math.atan2(y, x);
1691+
return rad / Math.PI * 180;
1692+
}
1693+
16091694
export default Geometry;
16101695

0 commit comments

Comments
 (0)