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
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
| //Class for interacting with ArcGIS Server image services
//Bill Dollins - Zekiah Technologies
//Modified from AgsDynamicLayer.js by DTSAgile
L.AgsImageLayer = L.Class.extend({
includes: L.Mixin.Events,
options: {
minZoom: 0,
maxZoom: 18,
attribution: '',
opacity: 1,
format: 'PNG8',
bandids: '',
compressionquality: 0,
interpolation: 'RSP_NearestNeighbor',
pixelType: 'U8',
unloadInvisibleTiles: L.Browser.mobileWebkit
},
initialize: function (/*String*/url, /*Object*/options) {
L.Util.setOptions(this, options);
this._url = url;
},
//public properties that modify the map
setInterpolation: function (interpolation) {
this.options.interpolation = interpolation;
},
getInterpolation: function () {
return this.options.interpolation;
},
setOpacity: function (opacity) {
//set it immediately
if (this._image) {
this._image.style.opacity = opacity;
// stupid webkit hack to force redrawing of tiles
this._image.style.webkitTransform += ' translate(0,0)';
}
this.options.opacity = opacity;
},
getOpacity: function () {
return this.options.opacity;
},
reset: function () {
this._reset();
},
update: function () {
// var topLeft = this._map.latLngToLayerPoint(this._map.getBounds().getNorthWest()),
// bottomRight = this._map.latLngToLayerPoint(this._map.getBounds().getSouthEast()),
// size = bottomRight.subtract(topLeft);
// L.DomUtil.setPosition(this._image, topLeft);
// this._image.style.width = size.x + 'px';
// this._image.style.height = size.y + 'px';
this._image.updating = false;
this._updateLayer();
},
show: function () {
this._image.style.display = 'block';
this._image.style.visibility = 'visible';
},
hide: function () {
this._image.style.display = 'none';
},
isVisible: function () {
return this._image.style.display === 'block';
},
onAdd: function (map) {
this._map = map;
this._reset();
map.on('viewreset', this._reset, this);
map.on('moveend', this._moveEnd, this);
map.on('zoomend', this._zoomEnd, this);
},
onRemove: function (map) {
map.getPanes().mapPane.removeChild(this._image);
map.off('viewreset', this._reset, this);
map.off('moveend', this._moveEnd, this);
map.off('zoomend', this._zoomEnd, this);
},
_initImage: function () {
this._image = L.DomUtil.create('img', 'leaflet-image-layer');
this._image.style.visibility = 'hidden';
this._image.style.opacity = this.options.opacity;
this._image.style.display = 'block';
//TODO createImage util method to remove duplication
L.Util.extend(this._image, {
onselectstart: L.Util.falseFn,
onmousemove: L.Util.falseFn,
onload: this._onImageLoad,
src: this._getImageUrl(),
updating: false,
agsLayer: this,
map: this._map
});
this._map.getPanes().mapPane.appendChild(this._image);
},
_getImageUrl: function () {
//construct the export image url
var bnds = this._map.getBounds();
var sz = this._map.getSize();
//bboxsr & imagesr params need to be specified like so to avoid alignment problems on some map services - not sure why
var bbox = 'bbox=' + bnds.getSouthEast().lng + '%2C' + bnds.getSouthEast().lat + '%2C' + bnds.getNorthWest().lng + '%2C' + bnds.getNorthWest().lat + '&bboxsr=4326&imageSR=3857';
var size = '&size=' + sz.x + '%2C' + sz.y;
var format = '&format=' + this.options.format;
var pixeltype = '&pixelType=' + this.options.pixelType;
var interpolation = '&interpolation=' + this.options.interpolation;
//Some of the following parameters are supported by ArcGIS Server Image Services but not implemented here.
//They have been included as placeholders.
var nodata = '&noData=';
var compressionquality = '&compressionQuality=' + this.options.compressionquality;
var bandids = '&bandIds=' + this.options.bandids;
var mosaicprops = '&mosaicProperties=';
var viewpointprops = '&viewpointProperties=';
var url = this._url + '/exportImage?' + bbox + size + format + pixeltype + nodata + interpolation + compressionquality + bandids + mosaicprops + viewpointprops + '&f=image';
return url; // this._url + '/export?' + bbox + size + layers + format + transparent + '&f=image';
},
_updateLayer: function () {
if (!this._image.updating) {
//console.log('Updating layer NW: ' + map.getBounds().getNorthWest());
this._image.updating = true;
//update the src based on the new location
this._image.src = this._getImageUrl();
//reset the image location on the map
// //hang the info on the image, we'll actually update it onload to make sure we don't reposition it before the new image comes down
//this doesn't seem to work on mobile
// this._image.topLeft = this._map.latLngToLayerPoint(this._map.getBounds().getNorthWest());
// var bottomRight = this._map.latLngToLayerPoint(this._map.getBounds().getSouthEast());
// this._image.size = bottomRight.subtract(this._image.topLeft);
var topLeft = this._map.latLngToLayerPoint(this._map.getBounds().getNorthWest()),
bottomRight = this._map.latLngToLayerPoint(this._map.getBounds().getSouthEast()),
size = bottomRight.subtract(topLeft);
L.DomUtil.setPosition(this._image, topLeft);
this._image.style.width = size.x + 'px';
this._image.style.height = size.y + 'px';
}
},
_moveEnd: function () {
//console.log('in _moveEnd : NW: ' + map.getBounds().getNorthWest());
//don't set display:none for moves - makes for smoother panning - no flicker
//oops, that didn't work on mobile
this._image.style.display = 'none';
this._updateLayer();
},
_zoomEnd: function () {
//console.log('in _moveEnd');
// //zoom the image...(animate it?)
// //L.DomUtil.setPosition(this, this.topLeft);
// //debugger;
// //it's gonna be something like this but it's not quite right - also will need to get/ calculate the correct factor (using 1.5 below) and change it for zoom out
// //and we need to properly calculate the new left and top - just hard coded approximate values below
// this._image.style.left = '-420px';
// this._image.style.top = '-228px';
// this._image.style.width = this._image.width * 1.5 + 'px';
// this._image.style.height = this._image.height * 1.5 + 'px';
//for now, we'll just do this
this._image.style.display = 'none';
this._updateLayer();
},
_reset: function () {
if (this._image) {
this._map.getPanes().mapPane.removeChild(this._image);
}
this._initImage();
this._updateLayer();
},
_onImageLoad: function () {
// //reset the image location on the map - doing it this way does not seem to work on mobile
// L.DomUtil.setPosition(this, this.topLeft);
// this.style.width = this.size.x + 'px';
// this.style.height = this.size.y + 'px';
//this is the image
//make sure it's visible and reset the updating flag
this.style.visibility = 'visible';
this.style.display = 'block';
this.updating = false;
}
});
|