├── www
├── robots.txt
├── lib
│ ├── images
│ │ ├── flag.png
│ │ ├── calibrat.png
│ │ ├── ioffset.png
│ │ ├── ioffsetd.png
│ │ ├── layers.png
│ │ ├── calibratd.png
│ │ ├── layers-2x.png
│ │ ├── marker-icon.png
│ │ ├── marker-shadow.png
│ │ ├── marker-icon-2x.png
│ │ └── marker-icon@2x.png
│ ├── MarkerCluster.css
│ ├── MarkerCluster.Default.ie.css
│ ├── MarkerCluster.Default.css
│ ├── TileLayer.Grayscale.js
│ ├── Permalink.js
│ ├── heatmap-leaflet.js
│ ├── leaflet-heatmap.js
│ ├── leaflet.css
│ ├── leaflet.markercluster.js
│ └── heatmap.js
├── download
│ ├── .htaccess
│ └── HEADER.html
├── .htaccess
├── config.php.sample
├── map.html
├── iodb-web.php
└── iodb.php
├── .gitignore
├── scripts
├── prune_archive.sh
└── iodb_backup.sh
├── composer.json
├── .htaccess
├── LICENSE
├── README.md
└── composer.lock
/www/robots.txt:
--------------------------------------------------------------------------------
1 | User-agent: *
2 | Disallow: /download/
3 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *.swp
2 | www/config.php
3 | vendor/
4 | www/download/*.gz
5 |
--------------------------------------------------------------------------------
/www/lib/images/flag.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zverik/iodb/master/www/lib/images/flag.png
--------------------------------------------------------------------------------
/www/lib/images/calibrat.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zverik/iodb/master/www/lib/images/calibrat.png
--------------------------------------------------------------------------------
/www/lib/images/ioffset.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zverik/iodb/master/www/lib/images/ioffset.png
--------------------------------------------------------------------------------
/www/lib/images/ioffsetd.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zverik/iodb/master/www/lib/images/ioffsetd.png
--------------------------------------------------------------------------------
/www/lib/images/layers.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zverik/iodb/master/www/lib/images/layers.png
--------------------------------------------------------------------------------
/www/lib/images/calibratd.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zverik/iodb/master/www/lib/images/calibratd.png
--------------------------------------------------------------------------------
/www/lib/images/layers-2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zverik/iodb/master/www/lib/images/layers-2x.png
--------------------------------------------------------------------------------
/www/lib/images/marker-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zverik/iodb/master/www/lib/images/marker-icon.png
--------------------------------------------------------------------------------
/www/lib/images/marker-shadow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zverik/iodb/master/www/lib/images/marker-shadow.png
--------------------------------------------------------------------------------
/www/lib/images/marker-icon-2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zverik/iodb/master/www/lib/images/marker-icon-2x.png
--------------------------------------------------------------------------------
/www/lib/images/marker-icon@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zverik/iodb/master/www/lib/images/marker-icon@2x.png
--------------------------------------------------------------------------------
/www/download/.htaccess:
--------------------------------------------------------------------------------
1 | Options +Indexes
2 | IndexOrderDefault Descending Date
3 | IndexOptions +SuppressColumnSorting
4 | HeaderName HEADER.html
5 |
6 |
--------------------------------------------------------------------------------
/scripts/prune_archive.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | find "$(dirname "$0")/download" -name 'iodb*' ! -name '*01.*' ! -name '*-1303*' ! -name "*-$(date +%y%m)*" ! -name '*latest*' -delete
3 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "zverik/iodb",
3 | "description": "Imagery Offset Database Backend",
4 | "type": "project",
5 | "require": {
6 | "jbelien/oauth2-openstreetmap": "^0.1.2"
7 | },
8 | "license": "WTFPL"
9 | }
10 |
--------------------------------------------------------------------------------
/www/download/HEADER.html:
--------------------------------------------------------------------------------
1 |
Imagery Offset Database Archives
2 | Those are archives of the Imagery Offset Database. All files are distributed under a PDDL license. The latest extracts in XML and JSON formats are updated hourly.
3 |
--------------------------------------------------------------------------------
/www/lib/MarkerCluster.css:
--------------------------------------------------------------------------------
1 | .leaflet-cluster-anim .leaflet-marker-icon, .leaflet-cluster-anim .leaflet-marker-shadow {
2 | -webkit-transition: -webkit-transform 0.2s ease-out, opacity 0.2s ease-in;
3 | -moz-transition: -moz-transform 0.2s ease-out, opacity 0.2s ease-in;
4 | -o-transition: -o-transform 0.2s ease-out, opacity 0.2s ease-in;
5 | transition: transform 0.2s ease-out, opacity 0.2s ease-in;
6 | }
7 |
--------------------------------------------------------------------------------
/.htaccess:
--------------------------------------------------------------------------------
1 | DirectoryIndex iodb.php
2 |
3 | Options -Indexes -MultiViews +FollowSymLinks
4 |
5 |
6 | RewriteEngine On
7 |
8 | RewriteCond %{REQUEST_FILENAME} -f
9 | RewriteRule ^ - [L]
10 | RewriteRule ^(download|lib) - [L]
11 | RewriteRule ^iodb\.php$ - [L]
12 | RewriteRule ^map map.html [L]
13 | RewriteRule ^$ iodb.php [QSA,L]
14 | RewriteRule .* iodb.php?action=$0 [QSA,L]
15 |
16 |
17 |
18 | CharsetRecodeMultipartForms Off
19 | CharsetSourceEnc utf-8
20 |
21 |
22 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
2 | Version 2, December 2004
3 |
4 | Copyright (C) 2004 Sam Hocevar
5 |
6 | Everyone is permitted to copy and distribute verbatim or modified
7 | copies of this license document, and changing it is allowed as long
8 | as the name is changed.
9 |
10 | DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
11 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
12 |
13 | 0. You just DO WHAT THE FUCK YOU WANT TO.
14 |
15 |
--------------------------------------------------------------------------------
/www/.htaccess:
--------------------------------------------------------------------------------
1 | DirectoryIndex iodb.php
2 |
3 | Options -Indexes -MultiViews
4 |
5 |
6 | RewriteEngine On
7 |
8 | RewriteCond %{REQUEST_FILENAME} -f
9 | RewriteRule ^ - [L]
10 | RewriteRule ^(download|lib) - [L]
11 | RewriteRule ^iodb\.php$ - [L]
12 | RewriteRule ^map map.html [L]
13 | RewriteRule ^$ iodb.php [QSA,L]
14 | RewriteRule .* iodb.php?action=$0 [QSA,L,UnsafeAllow3F]
15 |
16 |
17 |
18 | CharsetRecodeMultipartForms Off
19 | CharsetSourceEnc utf-8
20 |
21 |
22 |
--------------------------------------------------------------------------------
/www/lib/MarkerCluster.Default.ie.css:
--------------------------------------------------------------------------------
1 | /* IE 6-8 fallback colors */
2 | .marker-cluster-small {
3 | background-color: rgb(181, 226, 140);
4 | }
5 | .marker-cluster-small div {
6 | background-color: rgb(110, 204, 57);
7 | }
8 |
9 | .marker-cluster-medium {
10 | background-color: rgb(241, 211, 87);
11 | }
12 | .marker-cluster-medium div {
13 | background-color: rgb(240, 194, 12);
14 | }
15 |
16 | .marker-cluster-large {
17 | background-color: rgb(253, 156, 115);
18 | }
19 | .marker-cluster-large div {
20 | background-color: rgb(241, 128, 23);
21 | }
22 |
23 |
--------------------------------------------------------------------------------
/scripts/iodb_backup.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | IODB=/var/www/sites/offsets.textual.ru/iodb.php
3 | PHP=/usr/bin/php
4 | GZIP=/usr/bin/gzip
5 | TARGET=/var/www/sites/offsets.textual.ru/download
6 | TMPDIR=/tmp
7 | DATE=`date +%y%m%d`
8 |
9 | $PHP $IODB xml 2> /dev/null | $GZIP > $TMPDIR/iodb-latest.xml.gz
10 | $PHP $IODB json 2> /dev/null | $GZIP > $TMPDIR/iodb-latest.json.gz
11 |
12 | if [ ! -f $TARGET/iodb-$DATE.xml.gz ]; then
13 | cp $TMPDIR/iodb-latest.xml.gz $TARGET/iodb-$DATE.xml.gz
14 | cp $TMPDIR/iodb-latest.json.gz $TARGET/iodb-$DATE.json.gz
15 | fi
16 |
17 | mv $TMPDIR/iodb-latest.xml.gz $TARGET
18 | mv $TMPDIR/iodb-latest.json.gz $TARGET
19 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Imagery Offset Database
2 |
3 | This is a backend and web interface for imagery offset database.
4 |
5 | ## Installation
6 |
7 | Copy everything except `scripts` to a www document root. Edit `config.php`, in which
8 | you need to include OSM API key and database credentials. Then open the web interface
9 | and click "Create database".
10 |
11 | To publish regular backups of the database, use `iodb_backup` script.
12 |
13 | ## Author and License
14 |
15 | Written by Ilya Zverev, licensed WTFPL.
16 |
17 | Web interface uses [Leaflet](http://leafletjs.com) library and some plugins for it:
18 | heatmap.js, Leaflet.markercluster, Permalink and TileLayer.Grayscale. Those and other
19 | plugins can be downloaded from Leaflet's official website.
20 |
--------------------------------------------------------------------------------
/www/config.php.sample:
--------------------------------------------------------------------------------
1 |
21 |
--------------------------------------------------------------------------------
/www/lib/MarkerCluster.Default.css:
--------------------------------------------------------------------------------
1 | .marker-cluster-small {
2 | background-color: rgba(181, 226, 140, 0.6);
3 | }
4 | .marker-cluster-small div {
5 | background-color: rgba(110, 204, 57, 0.6);
6 | }
7 |
8 | .marker-cluster-medium {
9 | background-color: rgba(241, 211, 87, 0.6);
10 | }
11 | .marker-cluster-medium div {
12 | background-color: rgba(240, 194, 12, 0.6);
13 | }
14 |
15 | .marker-cluster-large {
16 | background-color: rgba(253, 156, 115, 0.6);
17 | }
18 | .marker-cluster-large div {
19 | background-color: rgba(241, 128, 23, 0.6);
20 | }
21 |
22 | .marker-cluster {
23 | background-clip: padding-box;
24 | border-radius: 20px;
25 | }
26 | .marker-cluster div {
27 | width: 30px;
28 | height: 30px;
29 | margin-left: 5px;
30 | margin-top: 5px;
31 |
32 | text-align: center;
33 | border-radius: 15px;
34 | font: 12px "Helvetica Neue", Arial, Helvetica, sans-serif;
35 | }
36 | .marker-cluster span {
37 | line-height: 30px;
38 | }
--------------------------------------------------------------------------------
/www/lib/TileLayer.Grayscale.js:
--------------------------------------------------------------------------------
1 | /*
2 | * L.TileLayer.Grayscale is a regular tilelayer with grayscale makeover.
3 | */
4 |
5 | L.TileLayer.Grayscale = L.TileLayer.extend({
6 | options: {
7 | quotaRed: 21,
8 | quotaGreen: 71,
9 | quotaBlue: 8,
10 | quotaDividerTune: 0,
11 | quotaDivider: function() {
12 | return this.quotaRed + this.quotaGreen + this.quotaBlue + this.quotaDividerTune;
13 | }
14 | },
15 |
16 | initialize: function (url, options) {
17 | options = options || {}
18 | options.crossOrigin = true;
19 | L.TileLayer.prototype.initialize.call(this, url, options);
20 |
21 | this.on('tileload', function(e) {
22 | this._makeGrayscale(e.tile);
23 | });
24 | },
25 |
26 | _createTile: function () {
27 | var tile = L.TileLayer.prototype._createTile.call(this);
28 | tile.crossOrigin = "Anonymous";
29 | return tile;
30 | },
31 |
32 | _makeGrayscale: function (img) {
33 | if (img.getAttribute('data-grayscaled'))
34 | return;
35 |
36 | img.crossOrigin = '';
37 | var canvas = document.createElement("canvas");
38 | canvas.width = img.width;
39 | canvas.height = img.height;
40 | var ctx = canvas.getContext("2d");
41 | ctx.drawImage(img, 0, 0);
42 |
43 | var imgd = ctx.getImageData(0, 0, canvas.width, canvas.height);
44 | var pix = imgd.data;
45 | for (var i = 0, n = pix.length; i < n; i += 4) {
46 | pix[i] = pix[i + 1] = pix[i + 2] = (this.options.quotaRed * pix[i] + this.options.quotaGreen * pix[i + 1] + this.options.quotaBlue * pix[i + 2]) / this.options.quotaDivider();
47 | }
48 | ctx.putImageData(imgd, 0, 0);
49 | img.setAttribute('data-grayscaled', true);
50 | img.src = canvas.toDataURL();
51 | }
52 | });
53 |
54 | L.tileLayer.grayscale = function (url, options) {
55 | return new L.TileLayer.Grayscale(url, options);
56 | };
57 |
--------------------------------------------------------------------------------
/www/lib/Permalink.js:
--------------------------------------------------------------------------------
1 | L.Control.Permalink = L.Control.extend({
2 | includes: L.Mixin.Events,
3 |
4 | options: {
5 | position: "bottomleft",
6 | useAnchor: true,
7 | useLocation: false,
8 | text: "Permalink"
9 | },
10 |
11 | initialize: function(options) {
12 | L.Util.setOptions(this, options);
13 | this._params = {};
14 | this._set_urlvars();
15 | this.on("update", this._set_center, this);
16 | for (var i in this) {
17 | if (typeof(i) === "string" && i.indexOf('initialize_') == 0)
18 | this[i]();
19 | }
20 | },
21 |
22 | onAdd: function(map) {
23 | this._container = L.DomUtil.create('div', 'leaflet-control-attribution leaflet-control-permalink');
24 | L.DomEvent.disableClickPropagation(this._container);
25 | this._map = map;
26 | this._href = L.DomUtil.create('a', null, this._container);
27 | this._href.innerHTML = this.options.text
28 |
29 | map.on('moveend', this._update_center, this);
30 | this.fire("update", {params: this._params})
31 | this._update_center();
32 |
33 | if (this.options.useAnchor && 'onhashchange' in window) {
34 | var _this = this, fn = window.onhashchange;
35 | window.onhashchange = function() {
36 | _this._set_urlvars();
37 | if (fn) return fn();
38 | }
39 | }
40 |
41 | this.fire('add', {map: map});
42 |
43 | return this._container;
44 | },
45 |
46 | _update_center: function() {
47 | if (!this._map) return;
48 |
49 | var center = this._round_point(this._map.getCenter());
50 | this._update({zoom: this._map.getZoom(), lat: center.lat, lon: center.lng});
51 | },
52 |
53 | _update_href: function() {
54 | var params = L.Util.getParamString(this._params);
55 | var sep = '?';
56 | if (this.options.useAnchor) sep = '#';
57 | var url = this._url_base + sep + params.slice(1);
58 | if (this._href) this._href.setAttribute('href', url);
59 | if (this.options.useLocation)
60 | location.replace('#' + params.slice(1));
61 | return url;
62 | },
63 |
64 | _round_point : function(point) {
65 | var bounds = this._map.getBounds(), size = this._map.getSize();
66 | var ne = bounds.getNorthEast(), sw = bounds.getSouthWest();
67 |
68 | var round = function (x, p) {
69 | if (p == 0) return x;
70 | shift = 1;
71 | while (p < 1 && p > -1) {
72 | x *= 10;
73 | p *= 10;
74 | shift *= 10;
75 | }
76 | return Math.floor(x)/shift;
77 | }
78 | point.lat = round(point.lat, (ne.lat - sw.lat) / size.y);
79 | point.lng = round(point.lng, (ne.lng - sw.lng) / size.x);
80 | return point;
81 | },
82 |
83 | _update: function(obj, source) {
84 | //console.info("Update", obj, this._params);
85 | for(var i in obj) {
86 | if (!obj.hasOwnProperty(i)) continue;
87 | if (obj[i] != null && obj[i] != undefined)
88 | this._params[i] = obj[i]
89 | else
90 | delete this._params[i];
91 | }
92 |
93 | this._update_href();
94 | },
95 |
96 | _set_urlvars: function()
97 | {
98 | this._url_base = window.location.href.split('#')[0];
99 |
100 | var p;
101 | if (this.options.useAnchor)
102 | p = L.UrlUtil.queryParse(L.UrlUtil.hash());
103 | else
104 | p = L.UrlUtil.queryParse(L.UrlUtil.query());
105 |
106 | function eq(x, y) {
107 | for(var i in x)
108 | if (x.hasOwnProperty(i) && x[i] != y[i])
109 | return false;
110 | return true;
111 | }
112 |
113 | if (eq(p, this._params) && eq(this._params, p))
114 | return;
115 | this._params = p;
116 | this._update_href();
117 | this.fire("update", {params: this._params})
118 | },
119 |
120 | _set_center: function(e)
121 | {
122 | //console.info("Update center", e);
123 | var params = e.params;
124 | if (params.zoom == undefined ||
125 | params.lat == undefined ||
126 | params.lon == undefined) return;
127 | this._map.setView(new L.LatLng(params.lat, params.lon), params.zoom);
128 | }
129 | });
130 |
131 | L.UrlUtil = {
132 | queryParse: function(s) {
133 | var p = {};
134 | var sep = "&";
135 | if (s.search("&") != -1)
136 | sep = "&";
137 | var params = s.split(sep);
138 | for(var i = 0; i < params.length; i++) {
139 | var tmp = params[i].split('=');
140 | if (tmp.length != 2) continue;
141 | p[tmp[0]] = tmp[1];
142 | }
143 | return p;
144 | },
145 |
146 | query: function() {
147 | var href = window.location.href.split('#')[0], idx = href.indexOf('?');
148 | if (idx < 0)
149 | return '';
150 | return href.slice(idx+1);
151 | },
152 |
153 | hash: function() { return window.location.hash.slice(1) },
154 |
155 | updateParamString: function (q, obj) {
156 | var p = L.UrlUtil.queryParse(q);
157 | for (var i in obj) {
158 | if (obj.hasOwnProperty(i))
159 | p[i] = obj[i];
160 | }
161 | return L.Util.getParamString(p).slice(1);
162 | }
163 | };
164 |
--------------------------------------------------------------------------------
/www/lib/heatmap-leaflet.js:
--------------------------------------------------------------------------------
1 | /*
2 | * heatmap.js 0.2 Leaflet overlay
3 | *
4 | * Copyright (c) 2012, Dominik Moritz
5 | * Dual-licensed under the MIT (http://www.opensource.org/licenses/mit-license.php)
6 | * and the Beerware (http://en.wikipedia.org/wiki/Beerware) license.
7 | *
8 | * Attribution for snippets: https://gist.github.com/2566567
9 | */
10 |
11 | L.TileLayer.HeatMap = L.TileLayer.Canvas.extend({
12 | options: {
13 | // calculate the maximum value on a per view basis instead of global
14 | // this creates issues when moving the map
15 | maxPerView: false,
16 | debug: false
17 | },
18 |
19 | initialize: function (options) {
20 | L.Util.setOptions(this, options);
21 |
22 | this._cache = {
23 | max: 0,
24 | bounds: {}
25 | };
26 |
27 | this._data = [];
28 |
29 | this.drawTile = function (tile, tilePoint, zoom) {
30 | var ctx = {
31 | tile: tile,
32 | tilePoint: tilePoint,
33 | zoom: zoom,
34 | heatmap: tile.heatmap
35 | };
36 |
37 | if (this.options.debug) {
38 | this._drawDebugInfo(ctx);
39 | }
40 | this._draw(ctx);
41 | };
42 | },
43 |
44 | // Add a dataset to be drawn. You might want to redraw() if you had previeous datasets.
45 | addData: function(dataset) {
46 | this._data = dataset;
47 | this._cache.max = this._calculateMaxValue(dataset);
48 | },
49 |
50 | _createTileProto: function () {
51 | var proto = this._tileProto = L.DomUtil.create('div', 'leaflet-tile');
52 |
53 | var tileSize = this.options.tileSize;
54 | proto.style.width = tileSize+"px";
55 | proto.style.height = tileSize+"px";
56 | proto.width = tileSize;
57 | proto.height = tileSize;
58 | },
59 |
60 | _createTile: function () {
61 | var tile = this._tileProto.cloneNode(false);
62 | tile.onselectstart = tile.onmousemove = L.Util.falseFn;
63 |
64 | var options = this.options;
65 | var config = {
66 | "radius": options.radius,
67 | "element": tile,
68 | "visible": true,
69 | "opacity": options.opacity * 100,
70 | "gradient": options.gradient
71 | };
72 | tile.heatmap = h337.create(config);
73 |
74 | return tile;
75 | },
76 |
77 | _drawDebugInfo: function (ctx) {
78 | var canvas = L.DomUtil.create('canvas', 'leaflet-tile-debug');
79 | var tileSize = this.options.tileSize;
80 | canvas.width = tileSize;
81 | canvas.height = tileSize;
82 | ctx['tile'].appendChild(canvas);
83 | ctx['canvas'] = canvas;
84 |
85 | var max = tileSize;
86 | var g = ctx.canvas.getContext('2d');
87 | g.strokeStyle = '#000000';
88 | g.fillStyle = '#FFFF00';
89 | g.strokeRect(0, 0, max, max);
90 | g.font = "12px Arial";
91 | g.fillRect(0, 0, 5, 5);
92 | g.fillRect(0, max - 5, 5, 5);
93 | g.fillRect(max - 5, 0, 5, 5);
94 | g.fillRect(max - 5, max - 5, 5, 5);
95 | g.fillRect(max / 2 - 5, max / 2 - 5, 10, 10);
96 | g.strokeText(ctx.tilePoint.x + ' ' + ctx.tilePoint.y + ' ' + ctx.zoom, max / 2 - 30, max / 2 - 10);
97 |
98 | this._drawPoint(ctx, [0,0])
99 | },
100 |
101 | _drawPoint: function (ctx, geom) {
102 | var p = this._tilePoint(ctx, geom);
103 | var c = ctx.canvas;
104 | var g = c.getContext('2d');
105 | g.beginPath();
106 | g.fillStyle = '#FF0000';
107 | g.arc(p.x, p.y, 4, 0, Math.PI * 2);
108 | g.closePath();
109 | g.fill();
110 | g.restore();
111 | },
112 |
113 | _tilePoint: function (ctx, coords) {
114 | // start coords to tile 'space'
115 | var s = ctx.tilePoint.multiplyBy(this.options.tileSize);
116 |
117 | // actual coords to tile 'space'
118 | var p = this._map.project(new L.LatLng(coords[1], coords[0]));
119 |
120 | // point to draw
121 | var x = Math.round(p.x - s.x);
122 | var y = Math.round(p.y - s.y);
123 | return {
124 | x: x,
125 | y: y
126 | };
127 | },
128 |
129 | // checks whether the point is inside a tile
130 | _isInTile: function(localXY, padding) {
131 | padding = padding || this.options.radius;
132 | var bounds = this._cache.bounds[padding];
133 | if (!bounds) {
134 | var tileSize = this.options.tileSize;
135 | var p1 = new L.Point(-padding, -padding); //topLeft
136 | var p2 = new L.Point(padding+tileSize, padding+tileSize); //bottomRight
137 | bounds = this._cache.bounds[padding] = new L.Bounds(p1, p2);
138 | };
139 | return bounds.contains([localXY.x, localXY.y]);
140 | },
141 |
142 | // get the max value of the dataset
143 | _getMaxValue: function() {
144 | if (this.options.maxPerView) {
145 | var dataset = [];
146 | var mapBounds = this._map.getBounds();
147 | this._data.forEach(function(item){
148 | if (mapBounds.contains([item.lat, item.lon])) {
149 | dataset.push(item);
150 | };
151 | });
152 |
153 | return this._calculateMaxValue(dataset)
154 | } else {
155 | return this._cache.max;
156 | }
157 | },
158 |
159 | _calculateMaxValue: function(dataset) {
160 | array = [];
161 | dataset.forEach(function(item){
162 | array.push(item.value || item.count);
163 | });
164 | return Math.max.apply(Math, array);
165 | },
166 |
167 | _draw: function(ctx) {
168 |
169 | var heatmap = ctx.heatmap
170 | heatmap.clear();
171 |
172 | var pointsInTile = [];
173 | if (this._data.length > 0) {
174 | for (var i=0, l=this._data.length; i 0) {
186 | var len = pointOrArray.length;
187 | while(len--) {
188 | this.addData(pointOrArray[len]);
189 | }
190 | } else {
191 | var latField = this.cfg.latField || 'lat';
192 | var lngField = this.cfg.lngField || 'lng';
193 | var valueField = this.cfg.valueField || 'value';
194 | var entry = pointOrArray;
195 | var latlng = new L.LatLng(entry[latField], entry[lngField]);
196 | var dataObj = { latlng: latlng };
197 |
198 | dataObj[valueField] = entry[valueField];
199 | this._max = Math.max(this._max, dataObj[valueField]);
200 | this._min = Math.min(this._min, dataObj[valueField]);
201 |
202 | if (entry.radius) {
203 | dataObj.radius = entry.radius;
204 | }
205 | this._data.push(dataObj);
206 | this._draw();
207 | }
208 | },
209 | _reset: function () {
210 | this._origin = this._map.layerPointToLatLng(new L.Point(0, 0));
211 |
212 | var size = this._map.getSize();
213 | if (this._width !== size.x || this._height !== size.y) {
214 | this._width = size.x;
215 | this._height = size.y;
216 |
217 | this._el.style.width = this._width + 'px';
218 | this._el.style.height = this._height + 'px';
219 |
220 | this._heatmap._renderer.setDimensions(this._width, this._height);
221 | }
222 | this._draw();
223 | }
224 | });
225 |
226 | HeatmapOverlay.CSS_TRANSFORM = (function() {
227 | var div = document.createElement('div');
228 | var props = [
229 | 'transform',
230 | 'WebkitTransform',
231 | 'MozTransform',
232 | 'OTransform',
233 | 'msTransform'
234 | ];
235 |
236 | for (var i = 0; i < props.length; i++) {
237 | var prop = props[i];
238 | if (div.style[prop] !== undefined) {
239 | return prop;
240 | }
241 | }
242 | return props[0];
243 | })();
244 |
245 | return HeatmapOverlay;
246 | });
--------------------------------------------------------------------------------
/www/map.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Imagery Offsets Map
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
67 |
206 |
207 |
208 |
209 |
213 |
218 |
224 |
225 |
228 |
229 |