/
extent.js
136 lines (120 loc) · 4.43 KB
/
extent.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
// Extent
// ----------
// An object representing a map's rectangular extent, defined by its north,
// south, east and west bounds.
MM.Extent = function(north, west, south, east) {
if (north instanceof MM.Location &&
west instanceof MM.Location) {
var northwest = north,
southeast = west;
north = northwest.lat;
west = northwest.lon;
south = southeast.lat;
east = southeast.lon;
}
if (isNaN(south)) south = north;
if (isNaN(east)) east = west;
this.north = Math.max(north, south);
this.south = Math.min(north, south);
this.east = Math.max(east, west);
this.west = Math.min(east, west);
};
MM.Extent.prototype = {
// boundary attributes
north: 0,
south: 0,
east: 0,
west: 0,
copy: function() {
return new MM.Extent(this.north, this.west, this.south, this.east);
},
toString: function(precision) {
if (isNaN(precision)) precision = 3;
return [
this.north.toFixed(precision),
this.west.toFixed(precision),
this.south.toFixed(precision),
this.east.toFixed(precision)
].join(", ");
},
// getters for the corner locations
northWest: function() {
return new MM.Location(this.north, this.west);
},
southEast: function() {
return new MM.Location(this.south, this.east);
},
northEast: function() {
return new MM.Location(this.north, this.east);
},
southWest: function() {
return new MM.Location(this.south, this.west);
},
// getter for the center location
center: function() {
return new MM.Location(
this.south + (this.north - this.south) / 2,
this.east + (this.west - this.east) / 2
);
},
// extend the bounds to include a location's latitude and longitude
encloseLocation: function(loc) {
if (loc.lat > this.north) this.north = loc.lat;
if (loc.lat < this.south) this.south = loc.lat;
if (loc.lon > this.east) this.east = loc.lon;
if (loc.lon < this.west) this.west = loc.lon;
},
// extend the bounds to include multiple locations
encloseLocations: function(locations) {
var len = locations.length;
for (var i = 0; i < len; i++) {
this.encloseLocation(locations[i]);
}
},
// reset bounds from a list of locations
setFromLocations: function(locations) {
var len = locations.length,
first = locations[0];
this.north = this.south = first.lat;
this.east = this.west = first.lon;
for (var i = 1; i < len; i++) {
this.encloseLocation(locations[i]);
}
},
// extend the bounds to include another extent
encloseExtent: function(extent) {
if (extent.north > this.north) this.north = extent.north;
if (extent.south < this.south) this.south = extent.south;
if (extent.east > this.east) this.east = extent.east;
if (extent.west < this.west) this.west = extent.west;
},
// determine if a location is within this extent
containsLocation: function(loc) {
return loc.lat >= this.south &&
loc.lat <= this.north &&
loc.lon >= this.west &&
loc.lon <= this.east;
},
// turn an extent into an array of locations containing its northwest
// and southeast corners (used in MM.Map.setExtent())
toArray: function() {
return [this.northWest(), this.southEast()];
}
};
MM.Extent.fromString = function(str) {
var parts = str.split(/\s*,\s*/);
if (parts.length != 4) {
throw "Invalid extent string (expecting 4 comma-separated numbers)";
}
return new MM.Extent(
parseFloat(parts[0]),
parseFloat(parts[1]),
parseFloat(parts[2]),
parseFloat(parts[3])
);
};
MM.Extent.fromArray = function(locations) {
var extent = new MM.Extent();
extent.setFromLocations(locations);
return extent;
};