forked from RedfishGroup/LeafletElementOverlay
-
Notifications
You must be signed in to change notification settings - Fork 0
/
worldFile.js
147 lines (133 loc) · 4.63 KB
/
worldFile.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
136
137
138
139
140
141
142
143
144
145
146
147
/*
Parse and display a world file
http://en.wikipedia.org/wiki/World_file
Cody Smith and Redfish Group 2015
usgage:
var urlTest = new L.WorldFile({imageUrl:"data/splat.png", textUrl:"data/splat.pgw"})
urlTest.addTo(map)
*/
L.WorldFile = L.ElementOverlay.extend({
params: {a:1, b:0, c:0, d:0, e:1, f:0},
initialize: function (options) { //options {imgUrl, textUrl}
console.log('init called')
this.refreshWorldFile(options)
L.setOptions(this, options)
this.TRANSFORMORIGIN = L.DomUtil.testProp(['TransformOrigin', 'WebkitTransformOrigin', 'MozTransformOrigin', 'msTransformOrigin', 'OTransformOrigin'])
},
// change the world file
//
refreshWorldFile: function(options) {
// check
if( !options.image && !options.imageUrl) {
throw('no image specified. ')
}
if( !options.params && !options.text && !options.textUrl) {
throw('no world file text specified ')
}
if( options.params) {
this.params = options.params
} else if( options.text) {
this.parseText(options.text)
} else if( options.textUrl) {
this.loadText(options.textUrl)
}
this.on('load', function(){
this.parseParams(this.params)
}.bind(this))
this.setUrl(options.image || options.imageUrl)
},
// Load the text from the network
//
loadText: function(textUrl) {
var oReq = new XMLHttpRequest()
oReq.onload = function(e){
this.parseText(e.target.responseText)
}.bind(this)
oReq.open("get", textUrl, true)
oReq.send()
},
// Parse a standard world file in epsg:4326. Todo support other projections
//
parseText: function(text) {
this.worldFileText = text
var items = text.split("\n")
if(items.length < 6) {
throw("world file not in correct format")
}
for( var i=0; i < 6; i++) {
var it=items[i];
items[i] = Number(it)
if( items[i] == NaN){
throw(" world file format error" + items[i])
}
}
var params = {a:items[0], b:items[2], c:items[4], d:items[1], e:items[3], f:items[5]}
this.params = params
this.parseParams()
},
parseParams:function(params){
params = params || this.params
if( this._image && params){
this.params = params
this._reset()
}
},
// convert image pixel coords to lat lon
//
pixelToWorld: function(x,y) {
var wp = this.params
var lon = wp.a*x + wp.b*y + wp.c
var lat = wp.d*x + wp.e*y + wp.f
return L.latLng(lat,lon)
},
// Converts a latlng on the world to a pixel coordinate in the map's
// div.
latlngToContainerPoint: function(latlng) {
var pixel_on_world = this._map.latLngToLayerPoint(latlng)
var pixel_in_container = this._map.layerPointToContainerPoint(pixel_on_world)
return pixel_in_container
},
// update the css for the element
//
_updateTransform: function() {
var image = this._image
var wid = image.naturalWidth || image.width
var hei = image.naturalHeight || image.height
// if the above measurements fail it is probably a div element
if( !wid || hei){
wid = image.offsetWidth
hei = image.offsetHeight
}
var lr = this.pixelToWorld(wid,hei)
var ul = this.pixelToWorld(0,0)
var ll = this.pixelToWorld(0,hei)
var ur = this.pixelToWorld(wid,0)
var markerLr = this.latlngToContainerPoint(lr)
var markerUl = this.latlngToContainerPoint(ul)
var markerLl = this.latlngToContainerPoint(ll)
var markerUr = this.latlngToContainerPoint(ur)
var offset = this._map.layerPointToContainerPoint( new L.Point(0,0))
//calculate transform matrix
var m11 = (markerUr.x - markerUl.x) / wid
var m12 = (markerUr.y - markerUl.y) / wid
var m21 = (markerLr.x - markerUr.x) / hei
var m22 = (markerLr.y - markerUr.y) / hei
var dx = markerUl.x - offset.x
var dy = markerUl.y - offset.y
//there it is
var matrix3d = "matrix(" +m11+ ", "+m21+", "+m12+", "+m22+", "+dx+", "+dy+")"
//Set the style
image.style[this.TRANSFORMORIGIN] = '0 0'
image.style['transform'] = matrix3d
},
// gets called by leaflet
//
_animateZoom: function (e) {
this._updateTransform()
},
// gets called after the zoom has changed
//
_reset: function () {
this._updateTransform()
},
})