add www directory

This commit is contained in:
kamba4 2024-09-12 19:22:07 +00:00
commit 832c581044
219 changed files with 12487 additions and 0 deletions

View file

@ -0,0 +1,23 @@
Copyright (c) 2010-2021, Vladimir Agafonkin
Copyright (c) 2010-2011, CloudMade
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are
permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this list of
conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this list
of conditions and the following disclaimer in the documentation and/or other materials
provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View file

@ -0,0 +1,32 @@
<img width="600" src="https://rawgit.com/Leaflet/Leaflet/master/src/images/logo.svg" alt="Leaflet" />
Leaflet is the leading open-source JavaScript library for **mobile-friendly interactive maps**.
Weighing just about 39 KB of gzipped JS plus 4 KB of gzipped CSS code, it has all the mapping [features][] most developers ever need.
Leaflet is designed with *simplicity*, *performance* and *usability* in mind.
It works efficiently across all major desktop and mobile platforms out of the box,
taking advantage of HTML5 and CSS3 on modern browsers while being accessible on older ones too.
It can be extended with a huge amount of [plugins][],
has a beautiful, easy to use and [well-documented][] API
and a simple, readable [source code][] that is a joy to [contribute][] to.
For more info, docs and tutorials, check out the [official website][].<br>
For **Leaflet downloads** (including the built master version), check out the [download page][].
We're happy to meet new contributors.
If you want to **get involved** with Leaflet development, check out the [contribution guide][contribute].
Let's make the best mapping library that will ever exist,
and push the limits of what's possible with online maps!
[![Build Status](https://travis-ci.org/Leaflet/Leaflet.svg?branch=master)](https://travis-ci.org/Leaflet/Leaflet)
[contributors]: https://github.com/Leaflet/Leaflet/graphs/contributors
[features]: http://leafletjs.com/#features
[plugins]: http://leafletjs.com/plugins.html
[well-documented]: http://leafletjs.com/reference.html "Leaflet API reference"
[source code]: https://github.com/Leaflet/Leaflet "Leaflet GitHub repository"
[hosted on GitHub]: http://github.com/Leaflet/Leaflet
[contribute]: https://github.com/Leaflet/Leaflet/blob/master/CONTRIBUTING.md "A guide to contributing to Leaflet"
[official website]: http://leafletjs.com
[download page]: http://leafletjs.com/download.html

View file

@ -0,0 +1,640 @@
/* required styles */
.leaflet-pane,
.leaflet-tile,
.leaflet-marker-icon,
.leaflet-marker-shadow,
.leaflet-tile-container,
.leaflet-pane > svg,
.leaflet-pane > canvas,
.leaflet-zoom-box,
.leaflet-image-layer,
.leaflet-layer {
position: absolute;
left: 0;
top: 0;
}
.leaflet-container {
overflow: hidden;
}
.leaflet-tile,
.leaflet-marker-icon,
.leaflet-marker-shadow {
-webkit-user-select: none;
-moz-user-select: none;
user-select: none;
-webkit-user-drag: none;
}
/* Prevents IE11 from highlighting tiles in blue */
.leaflet-tile::selection {
background: transparent;
}
/* Safari renders non-retina tile on retina better with this, but Chrome is worse */
.leaflet-safari .leaflet-tile {
image-rendering: -webkit-optimize-contrast;
}
/* hack that prevents hw layers "stretching" when loading new tiles */
.leaflet-safari .leaflet-tile-container {
width: 1600px;
height: 1600px;
-webkit-transform-origin: 0 0;
}
.leaflet-marker-icon,
.leaflet-marker-shadow {
display: block;
}
/* .leaflet-container svg: reset svg max-width decleration shipped in Joomla! (joomla.org) 3.x */
/* .leaflet-container img: map is broken in FF if you have max-width: 100% on tiles */
.leaflet-container .leaflet-overlay-pane svg,
.leaflet-container .leaflet-marker-pane img,
.leaflet-container .leaflet-shadow-pane img,
.leaflet-container .leaflet-tile-pane img,
.leaflet-container img.leaflet-image-layer,
.leaflet-container .leaflet-tile {
max-width: none !important;
max-height: none !important;
}
.leaflet-container.leaflet-touch-zoom {
-ms-touch-action: pan-x pan-y;
touch-action: pan-x pan-y;
}
.leaflet-container.leaflet-touch-drag {
-ms-touch-action: pinch-zoom;
/* Fallback for FF which doesn't support pinch-zoom */
touch-action: none;
touch-action: pinch-zoom;
}
.leaflet-container.leaflet-touch-drag.leaflet-touch-zoom {
-ms-touch-action: none;
touch-action: none;
}
.leaflet-container {
-webkit-tap-highlight-color: transparent;
}
.leaflet-container a {
-webkit-tap-highlight-color: rgba(51, 181, 229, 0.4);
}
.leaflet-tile {
filter: inherit;
visibility: hidden;
}
.leaflet-tile-loaded {
visibility: inherit;
}
.leaflet-zoom-box {
width: 0;
height: 0;
-moz-box-sizing: border-box;
box-sizing: border-box;
z-index: 800;
}
/* workaround for https://bugzilla.mozilla.org/show_bug.cgi?id=888319 */
.leaflet-overlay-pane svg {
-moz-user-select: none;
}
.leaflet-pane { z-index: 400; }
.leaflet-tile-pane { z-index: 200; }
.leaflet-overlay-pane { z-index: 400; }
.leaflet-shadow-pane { z-index: 500; }
.leaflet-marker-pane { z-index: 600; }
.leaflet-tooltip-pane { z-index: 650; }
.leaflet-popup-pane { z-index: 700; }
.leaflet-map-pane canvas { z-index: 100; }
.leaflet-map-pane svg { z-index: 200; }
.leaflet-vml-shape {
width: 1px;
height: 1px;
}
.lvml {
behavior: url(#default#VML);
display: inline-block;
position: absolute;
}
/* control positioning */
.leaflet-control {
position: relative;
z-index: 800;
pointer-events: visiblePainted; /* IE 9-10 doesn't have auto */
pointer-events: auto;
}
.leaflet-top,
.leaflet-bottom {
position: absolute;
z-index: 1000;
pointer-events: none;
}
.leaflet-top {
top: 0;
}
.leaflet-right {
right: 0;
}
.leaflet-bottom {
bottom: 0;
}
.leaflet-left {
left: 0;
}
.leaflet-control {
float: left;
clear: both;
}
.leaflet-right .leaflet-control {
float: right;
}
.leaflet-top .leaflet-control {
margin-top: 10px;
}
.leaflet-bottom .leaflet-control {
margin-bottom: 10px;
}
.leaflet-left .leaflet-control {
margin-left: 10px;
}
.leaflet-right .leaflet-control {
margin-right: 10px;
}
/* zoom and fade animations */
.leaflet-fade-anim .leaflet-tile {
will-change: opacity;
}
.leaflet-fade-anim .leaflet-popup {
opacity: 0;
-webkit-transition: opacity 0.2s linear;
-moz-transition: opacity 0.2s linear;
transition: opacity 0.2s linear;
}
.leaflet-fade-anim .leaflet-map-pane .leaflet-popup {
opacity: 1;
}
.leaflet-zoom-animated {
-webkit-transform-origin: 0 0;
-ms-transform-origin: 0 0;
transform-origin: 0 0;
}
.leaflet-zoom-anim .leaflet-zoom-animated {
will-change: transform;
}
.leaflet-zoom-anim .leaflet-zoom-animated {
-webkit-transition: -webkit-transform 0.25s cubic-bezier(0,0,0.25,1);
-moz-transition: -moz-transform 0.25s cubic-bezier(0,0,0.25,1);
transition: transform 0.25s cubic-bezier(0,0,0.25,1);
}
.leaflet-zoom-anim .leaflet-tile,
.leaflet-pan-anim .leaflet-tile {
-webkit-transition: none;
-moz-transition: none;
transition: none;
}
.leaflet-zoom-anim .leaflet-zoom-hide {
visibility: hidden;
}
/* cursors */
.leaflet-interactive {
cursor: pointer;
}
.leaflet-grab {
cursor: -webkit-grab;
cursor: -moz-grab;
cursor: grab;
}
.leaflet-crosshair,
.leaflet-crosshair .leaflet-interactive {
cursor: crosshair;
}
.leaflet-popup-pane,
.leaflet-control {
cursor: auto;
}
.leaflet-dragging .leaflet-grab,
.leaflet-dragging .leaflet-grab .leaflet-interactive,
.leaflet-dragging .leaflet-marker-draggable {
cursor: move;
cursor: -webkit-grabbing;
cursor: -moz-grabbing;
cursor: grabbing;
}
/* marker & overlays interactivity */
.leaflet-marker-icon,
.leaflet-marker-shadow,
.leaflet-image-layer,
.leaflet-pane > svg path,
.leaflet-tile-container {
pointer-events: none;
}
.leaflet-marker-icon.leaflet-interactive,
.leaflet-image-layer.leaflet-interactive,
.leaflet-pane > svg path.leaflet-interactive,
svg.leaflet-image-layer.leaflet-interactive path {
pointer-events: visiblePainted; /* IE 9-10 doesn't have auto */
pointer-events: auto;
}
/* visual tweaks */
.leaflet-container {
background: #ddd;
outline: 0;
}
.leaflet-container a {
color: #0078A8;
}
.leaflet-container a.leaflet-active {
outline: 2px solid orange;
}
.leaflet-zoom-box {
border: 2px dotted #38f;
background: rgba(255,255,255,0.5);
}
/* general typography */
.leaflet-container {
font: 12px/1.5 "Helvetica Neue", Arial, Helvetica, sans-serif;
}
/* general toolbar styles */
.leaflet-bar {
box-shadow: 0 1px 5px rgba(0,0,0,0.65);
border-radius: 4px;
}
.leaflet-bar a,
.leaflet-bar a:hover {
background-color: #fff;
border-bottom: 1px solid #ccc;
width: 26px;
height: 26px;
line-height: 26px;
display: block;
text-align: center;
text-decoration: none;
color: black;
}
.leaflet-bar a,
.leaflet-control-layers-toggle {
background-position: 50% 50%;
background-repeat: no-repeat;
display: block;
}
.leaflet-bar a:hover {
background-color: #f4f4f4;
}
.leaflet-bar a:first-child {
border-top-left-radius: 4px;
border-top-right-radius: 4px;
}
.leaflet-bar a:last-child {
border-bottom-left-radius: 4px;
border-bottom-right-radius: 4px;
border-bottom: none;
}
.leaflet-bar a.leaflet-disabled {
cursor: default;
background-color: #f4f4f4;
color: #bbb;
}
.leaflet-touch .leaflet-bar a {
width: 30px;
height: 30px;
line-height: 30px;
}
.leaflet-touch .leaflet-bar a:first-child {
border-top-left-radius: 2px;
border-top-right-radius: 2px;
}
.leaflet-touch .leaflet-bar a:last-child {
border-bottom-left-radius: 2px;
border-bottom-right-radius: 2px;
}
/* zoom control */
.leaflet-control-zoom-in,
.leaflet-control-zoom-out {
font: bold 18px 'Lucida Console', Monaco, monospace;
text-indent: 1px;
}
.leaflet-touch .leaflet-control-zoom-in, .leaflet-touch .leaflet-control-zoom-out {
font-size: 22px;
}
/* layers control */
.leaflet-control-layers {
box-shadow: 0 1px 5px rgba(0,0,0,0.4);
background: #fff;
border-radius: 5px;
}
.leaflet-control-layers-toggle {
background-image: url(images/layers.png);
width: 36px;
height: 36px;
}
.leaflet-retina .leaflet-control-layers-toggle {
background-image: url(images/layers-2x.png);
background-size: 26px 26px;
}
.leaflet-touch .leaflet-control-layers-toggle {
width: 44px;
height: 44px;
}
.leaflet-control-layers .leaflet-control-layers-list,
.leaflet-control-layers-expanded .leaflet-control-layers-toggle {
display: none;
}
.leaflet-control-layers-expanded .leaflet-control-layers-list {
display: block;
position: relative;
}
.leaflet-control-layers-expanded {
padding: 6px 10px 6px 6px;
color: #333;
background: #fff;
}
.leaflet-control-layers-scrollbar {
overflow-y: scroll;
overflow-x: hidden;
padding-right: 5px;
}
.leaflet-control-layers-selector {
margin-top: 2px;
position: relative;
top: 1px;
}
.leaflet-control-layers label {
display: block;
}
.leaflet-control-layers-separator {
height: 0;
border-top: 1px solid #ddd;
margin: 5px -10px 5px -6px;
}
/* Default icon URLs */
.leaflet-default-icon-path {
background-image: url(images/marker-icon.png);
}
/* attribution and scale controls */
.leaflet-container .leaflet-control-attribution {
background: #fff;
background: rgba(255, 255, 255, 0.7);
margin: 0;
}
.leaflet-control-attribution,
.leaflet-control-scale-line {
padding: 0 5px;
color: #333;
}
.leaflet-control-attribution a {
text-decoration: none;
}
.leaflet-control-attribution a:hover {
text-decoration: underline;
}
.leaflet-container .leaflet-control-attribution,
.leaflet-container .leaflet-control-scale {
font-size: 11px;
}
.leaflet-left .leaflet-control-scale {
margin-left: 5px;
}
.leaflet-bottom .leaflet-control-scale {
margin-bottom: 5px;
}
.leaflet-control-scale-line {
border: 2px solid #777;
border-top: none;
line-height: 1.1;
padding: 2px 5px 1px;
font-size: 11px;
white-space: nowrap;
overflow: hidden;
-moz-box-sizing: border-box;
box-sizing: border-box;
background: #fff;
background: rgba(255, 255, 255, 0.5);
}
.leaflet-control-scale-line:not(:first-child) {
border-top: 2px solid #777;
border-bottom: none;
margin-top: -2px;
}
.leaflet-control-scale-line:not(:first-child):not(:last-child) {
border-bottom: 2px solid #777;
}
.leaflet-touch .leaflet-control-attribution,
.leaflet-touch .leaflet-control-layers,
.leaflet-touch .leaflet-bar {
box-shadow: none;
}
.leaflet-touch .leaflet-control-layers,
.leaflet-touch .leaflet-bar {
border: 2px solid rgba(0,0,0,0.2);
background-clip: padding-box;
}
/* popup */
.leaflet-popup {
position: absolute;
text-align: center;
margin-bottom: 20px;
}
.leaflet-popup-content-wrapper {
padding: 1px;
text-align: left;
border-radius: 12px;
}
.leaflet-popup-content {
margin: 13px 19px;
line-height: 1.4;
}
.leaflet-popup-content p {
margin: 18px 0;
}
.leaflet-popup-tip-container {
width: 40px;
height: 20px;
position: absolute;
left: 50%;
margin-left: -20px;
overflow: hidden;
pointer-events: none;
}
.leaflet-popup-tip {
width: 17px;
height: 17px;
padding: 1px;
margin: -10px auto 0;
-webkit-transform: rotate(45deg);
-moz-transform: rotate(45deg);
-ms-transform: rotate(45deg);
transform: rotate(45deg);
}
.leaflet-popup-content-wrapper,
.leaflet-popup-tip {
background: white;
color: #333;
box-shadow: 0 3px 14px rgba(0,0,0,0.4);
}
.leaflet-container a.leaflet-popup-close-button {
position: absolute;
top: 0;
right: 0;
padding: 4px 4px 0 0;
border: none;
text-align: center;
width: 18px;
height: 14px;
font: 16px/14px Tahoma, Verdana, sans-serif;
color: #c3c3c3;
text-decoration: none;
font-weight: bold;
background: transparent;
}
.leaflet-container a.leaflet-popup-close-button:hover {
color: #999;
}
.leaflet-popup-scrolled {
overflow: auto;
border-bottom: 1px solid #ddd;
border-top: 1px solid #ddd;
}
.leaflet-oldie .leaflet-popup-content-wrapper {
-ms-zoom: 1;
}
.leaflet-oldie .leaflet-popup-tip {
width: 24px;
margin: 0 auto;
-ms-filter: "progid:DXImageTransform.Microsoft.Matrix(M11=0.70710678, M12=0.70710678, M21=-0.70710678, M22=0.70710678)";
filter: progid:DXImageTransform.Microsoft.Matrix(M11=0.70710678, M12=0.70710678, M21=-0.70710678, M22=0.70710678);
}
.leaflet-oldie .leaflet-popup-tip-container {
margin-top: -1px;
}
.leaflet-oldie .leaflet-control-zoom,
.leaflet-oldie .leaflet-control-layers,
.leaflet-oldie .leaflet-popup-content-wrapper,
.leaflet-oldie .leaflet-popup-tip {
border: 1px solid #999;
}
/* div icon */
.leaflet-div-icon {
background: #fff;
border: 1px solid #666;
}
/* Tooltip */
/* Base styles for the element that has a tooltip */
.leaflet-tooltip {
position: absolute;
padding: 6px;
background-color: #fff;
border: 1px solid #fff;
border-radius: 3px;
color: #222;
white-space: nowrap;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
pointer-events: none;
box-shadow: 0 1px 3px rgba(0,0,0,0.4);
}
.leaflet-tooltip.leaflet-clickable {
cursor: pointer;
pointer-events: auto;
}
.leaflet-tooltip-top:before,
.leaflet-tooltip-bottom:before,
.leaflet-tooltip-left:before,
.leaflet-tooltip-right:before {
position: absolute;
pointer-events: none;
border: 6px solid transparent;
background: transparent;
content: "";
}
/* Directions */
.leaflet-tooltip-bottom {
margin-top: 6px;
}
.leaflet-tooltip-top {
margin-top: -6px;
}
.leaflet-tooltip-bottom:before,
.leaflet-tooltip-top:before {
left: 50%;
margin-left: -6px;
}
.leaflet-tooltip-top:before {
bottom: 0;
margin-bottom: -12px;
border-top-color: #fff;
}
.leaflet-tooltip-bottom:before {
top: 0;
margin-top: -12px;
margin-left: -6px;
border-bottom-color: #fff;
}
.leaflet-tooltip-left {
margin-left: -6px;
}
.leaflet-tooltip-right {
margin-left: 6px;
}
.leaflet-tooltip-left:before,
.leaflet-tooltip-right:before {
top: 50%;
margin-top: -6px;
}
.leaflet-tooltip-left:before {
right: 0;
margin-right: -12px;
border-left-color: #fff;
}
.leaflet-tooltip-right:before {
left: 0;
margin-left: -12px;
border-right-color: #fff;
}

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,20 @@
Copyright 2013 - 2017, Jieter
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View file

@ -0,0 +1,83 @@
Leaflet-Semicircle.
-------------------
Allows drawing semicircles on leaflet maps.
It's an extension of Leaflet's [`L.Circle`](http://leafletjs.com/reference-1.1.0.html#circle),
and behaves like `L.Circle` if the a semicircle of almost 360 degrees is displayed.
Updated for use with leaflet 1.1.0.
## Provided classes: ##
<table>
<tr>
<td>
<code>L.SemiCircle</code>/
<code>L.SemiCircleMarker</code><br />
factories: <code>L.semiCircle</code>/<code>L.SemiCircleMarker</code>
</td>
<td>
Options:<br />
<code>startAngle</code>: start angle of the semicircle <br />
<code>stopAngle</code>: stop angle of the semicircle<br />
Angles are defined like compass courses: 0 = north, 90 = east, etc.
</td>
</tr>
## Provided methods: ##
<table>
<tr>
<td><code>L.SemiCircle.setStartAngle(angle)</code></td>
<td>Set the start angle of the circle to <code>angle</code> and redraw.</td>
</tr>
<tr>
<td><code>L.Circle.setStopAngle(angle)</code></td>
<td>Set the stop angle of the circle to <code>angle</code> and redraw.</td>
</tr>
<tr>
<td><code>L.Circle.setDirection(direction, size)</code></td>
<td>Set the <code>startAngle</code> to <code>direction - (0.5 * size)</code> and the <code>stopAngle</code> to <code>direction + (0.5 * size)</code> and redraw.</td>
</tr>
</table>
## Usage:
The plugin provides two ways to only display a part of the circle:
1. Use the `options` map and set `startAngle` and `stopAngle`.
2. Use `setDirection(direction, size)` to display a semicircle of `size` degrees at `direction`.
## Example:
[Live demo](http://jieter.github.com/Leaflet-semicircle/examples/semicircle.html)
Using `options.startAngle` and `options.stopAngle`:
```
L.semiCircle([51.5, -0.09], {
radius: 500,
startAngle: 45,
stopAngle: 135
}).addTo(map);
```
Draw the same semicircle using `setDirection(direction, size)`:
```
L.semiCircle([51.5, -0.09], {radius: 500})
.setDirection(90, 90)
.addTo(map);
```
## Screenshot:
[Live demo](http://jieter.github.com/Leaflet-semicircle/examples/semicircle.html)
![Semicircles screenshot](screenshot.png)
## Changelog
### 2.0.2 (2017-09-01)
- Fixed #24: instance check for canvas renderer
### 2.0.1 (2017-07-22)
- Fixed #14: Poleward displacement of circle center when radius is large.
### 2.0.0 (2017-07-09)
- Changed the API to stand-alone classes rather than overwriting `L.Circle` with an extension of itself.
- Added support for Leaflet 1.1.0

View file

@ -0,0 +1,196 @@
/**
* Semicircle extension for L.Circle.
* Jan Pieter Waagmeester <jieter@jieter.nl>
*
* This version is tested with leaflet 1.0.2
*/
(function (factory) {
if (typeof define === 'function' && define.amd) {
// AMD
define(['leaflet'], factory);
} else if (typeof module !== 'undefined' && typeof require !== 'undefined') {
// Node/CommonJS
module.exports = factory(require('leaflet'));
} else {
// Browser globals
if (typeof window.L === 'undefined') {
throw 'Leaflet must be loaded first';
}
factory(window.L);
}
})(function (L) {
var DEG_TO_RAD = Math.PI / 180;
// make sure 0 degrees is up (North) and convert to radians.
function fixAngle (angle) {
return (angle - 90) * DEG_TO_RAD;
}
// rotate point [x + r, y+r] around [x, y] by `angle` radians.
function rotated (p, angle, r) {
return p.add(
L.point(Math.cos(angle), Math.sin(angle)).multiplyBy(r)
);
}
L.Point.prototype.rotated = function (angle, r) {
return rotated(this, angle, r);
};
var semicircle = {
options: {
startAngle: 0,
stopAngle: 359.9999
},
startAngle: function () {
if (this.options.startAngle < this.options.stopAngle) {
return fixAngle(this.options.startAngle);
} else {
return fixAngle(this.options.stopAngle);
}
},
stopAngle: function () {
if (this.options.startAngle < this.options.stopAngle) {
return fixAngle(this.options.stopAngle);
} else {
return fixAngle(this.options.startAngle);
}
},
setStartAngle: function (angle) {
this.options.startAngle = angle;
return this.redraw();
},
setStopAngle: function (angle) {
this.options.stopAngle = angle;
return this.redraw();
},
setDirection: function (direction, degrees) {
if (degrees === undefined) {
degrees = 10;
}
this.options.startAngle = direction - (degrees / 2);
this.options.stopAngle = direction + (degrees / 2);
return this.redraw();
},
getDirection: function () {
return this.stopAngle() - (this.stopAngle() - this.startAngle()) / 2;
},
isSemicircle: function () {
var startAngle = this.options.startAngle,
stopAngle = this.options.stopAngle;
return (
!(startAngle === 0 && stopAngle > 359) &&
!(startAngle === stopAngle)
);
},
_containsPoint: function (p) {
function normalize (angle) {
while (angle <= -Math.PI) {
angle += 2.0 * Math.PI;
}
while (angle > Math.PI) {
angle -= 2.0 * Math.PI;
}
return angle;
}
var angle = Math.atan2(p.y - this._point.y, p.x - this._point.x);
var nStart = normalize(this.startAngle());
var nStop = normalize(this.stopAngle());
if (nStop <= nStart) {
nStop += 2.0 * Math.PI;
}
if (angle <= nStart) {
angle += 2.0 * Math.PI;
}
return (
nStart < angle && angle <= nStop &&
p.distanceTo(this._point) <= this._radius + this._clickTolerance()
);
}
};
L.SemiCircle = L.Circle.extend(semicircle);
L.SemiCircleMarker = L.CircleMarker.extend(semicircle);
L.semiCircle = function (latlng, options) {
return new L.SemiCircle(latlng, options);
};
L.semiCircleMarker = function (latlng, options) {
return new L.SemiCircleMarker(latlng, options);
};
var _updateCircleSVG = L.SVG.prototype._updateCircle;
var _updateCircleCanvas = L.Canvas.prototype._updateCircle;
L.SVG.include({
_updateCircle: function (layer) {
// If we want a circle, we use the original function
if (!(layer instanceof L.SemiCircle || layer instanceof L.SemiCircleMarker) ||
!layer.isSemicircle()) {
return _updateCircleSVG.call(this, layer);
}
if (layer._empty()) {
return this._setPath(layer, 'M0 0');
}
var p = layer._map.latLngToLayerPoint(layer._latlng),
r = layer._radius,
r2 = Math.round(layer._radiusY || r),
start = p.rotated(layer.startAngle(), r),
end = p.rotated(layer.stopAngle(), r);
var largeArc = (layer.options.stopAngle - layer.options.startAngle >= 180) ? '1' : '0';
var d = 'M' + p.x + ',' + p.y +
// line to first start point
'L' + start.x + ',' + start.y +
'A ' + r + ',' + r2 + ',0,' + largeArc + ',1,' + end.x + ',' + end.y +
' z';
this._setPath(layer, d);
}
});
L.Canvas.include({
_updateCircle: function (layer) {
// If we want a circle, we use the original function
if (!(layer instanceof L.SemiCircle || layer instanceof L.SemiCircleMarker) ||
!layer.isSemicircle()) {
return _updateCircleCanvas.call(this, layer);
}
if (!this._drawing || layer._empty()) { return; }
var p = layer._point,
ctx = this._ctx,
r = layer._radius,
s = (layer._radiusY || r) / r,
start = p.rotated(layer.startAngle(), r);
if (s !== 1) {
ctx.save();
ctx.scale(1, s);
}
ctx.beginPath();
ctx.moveTo(p.x, p.y);
ctx.lineTo(start.x, start.y);
ctx.arc(p.x, p.y, r, layer.startAngle(), layer.stopAngle());
ctx.lineTo(p.x, p.y);
if (s !== 1) {
ctx.restore();
}
this._fillStroke(ctx, layer);
}
});
});

299
www/sunders/add-lists.php Normal file
View file

@ -0,0 +1,299 @@
<?php
// Convert the content of the symbology JSON file to HTML.
function addListSymbology($jsonPath, $i18n, $i18nDefault) {
global $pathToWebFolder;
$decodedJSON = getDecodedJSON($jsonPath);
echo '<div class="slider-item slider-list">';
// Loop over the lists to display.
foreach($decodedJSON as $listObject) {
echo '<div class="slider-list-title">'.translate($i18n, $i18nDefault, $listObject->{'listTitle'}, [], [], []).'</div>';
// Loop over the entries of the current list.
foreach($listObject->{'listEntries'} as $listEntryObject) {
echo '<div class="slider-list-entry">
<div class="w-45">';
// Loop over the icons of the current list entry.
foreach($listEntryObject->{'icons'} as $icon) {
echo '<img src="'.$pathToWebFolder.'images/'.$icon->{'src'}.'" alt="'.translate($i18n, $i18nDefault, $icon->{'alt'}, [], [], []).'">';
}
echo '</div>
<div class="pl-20 w-315">'.translate($i18n, $i18nDefault, $listEntryObject->{'description'}, [], [], []).'</div>
</div>';
}
}
echo '</div>';
}
// Convert the content of the manual JSON file to HTML.
function addListManual($jsonPath, $i18n, $i18nDefault) {
global $pathToWebFolder;
$decodedJSON = getDecodedJSON($jsonPath);
echo '<div class="slider-item slider-list text-small">';
// Loop over the lists to display.
foreach($decodedJSON as $listObject) {
echo '<div class="slider-list-title">'.translate($i18n, $i18nDefault, $listObject->{'listTitle'}, [], [], []).'</div>';
// Loop over the entries of the current list.
foreach($listObject->{'listEntries'} as $listEntryObject) {
$keysAsHTMLArray = array();
$valuesAsHTMLArray = array();
// Loop over the keys of the current list entry.
foreach($listEntryObject->{'keys'} as $key) {
if (is_null($key->{'href'})) {
array_push($keysAsHTMLArray, translate($i18n, $i18nDefault, $key->{'key'}, [], [], []));
} else {
array_push($keysAsHTMLArray, translate($i18n, $i18nDefault, $key->{'key'}, [$key->{'href'}], [], []));
}
}
// Loop over the values of the current list entry.
foreach($listEntryObject->{'values'} as $value) {
if (is_null($value->{'href'})) {
array_push($valuesAsHTMLArray, translate($i18n, $i18nDefault, $value->{'value'}, [], [], []));
} else {
array_push($valuesAsHTMLArray, translate($i18n, $i18nDefault, $value->{'value'}, [$value->{'href'}], [], []));
}
}
echo '<div class="slider-list-entry">
<div class="w-120">';
echo implode('<br>', $keysAsHTMLArray);
echo '</div>';
// Some lists have an icon column.
if ($listObject->{'isListWithIcons'}) {
echo '<div class="pl-20 w-240">'
.implode('<br>', $valuesAsHTMLArray).'
</div>
<div class="w-20">';
$iconObject = $listEntryObject->{'icon'};
if (!is_null($iconObject)){
echo '<img src="'.$pathToWebFolder.'images/'.$iconObject->{'src'}.'" alt="'.translate($i18n, $i18nDefault, $iconObject->{'alt'}, [], [], []).'">';
}
} else {
echo '<div class="pl-20 w-260">'
.implode('<br>', $valuesAsHTMLArray).'';
}
echo '</div>
</div>';
}
// Some lists end with examples, i.e. 3 images with descriptions.
if (!is_null($listObject->{'examples'})) {
$examplesObject = $listObject->{'examples'};
$examplesObjectImages = $examplesObject->{'images'};
$examplesObjectDescriptions = $examplesObject->{'descriptions'};
echo '<div class="slider-list-entry">
<div>
<br>'.translate($i18n, $i18nDefault, 'examples', [], [], []).':
</div>
</div>
<div class="slider-list-entry">
<div class="example-boxes">';
for($i = 0; $i < count($examplesObjectImages); ++$i) {
$linesAsHTMLArray = array();
foreach($examplesObjectDescriptions[$i]->{'lines'} as $line) {
array_push($linesAsHTMLArray, translate($i18n, $i18nDefault, $line, [], [], []));
}
echo '<div class="example-box">
<div class="example-box-image">
<img src="'.$pathToWebFolder.'images/'.$examplesObjectImages[$i]->{'src'}.'" alt="'.translate($i18n, $i18nDefault, $examplesObjectImages[$i]->{'alt'}, [], [], []).'">
</div>
<div class="example-box-description">'
.implode('<br>', $linesAsHTMLArray).'
</div>
</div>';
}
echo ' </div>
</div>';
}
}
echo '</div>';
}
// Convert the content of the links JSON file to HTML.
/* function addListLinks($jsonPath, $i18n, $i18nDefault) {
global $pathToWebFolder;
$expandSectionCounter = 0;
$decodedJSON = getDecodedJSON($jsonPath);
echo '<div class="slider-item slider-list">';
// Loop over the lists to display.
foreach($decodedJSON as $listObject) {
echo '<div class="slider-list-title">'.translate($i18n, $i18nDefault, $listObject->{'listTitle'}, [], [], []).'</div>';
// Loop over the sections of the current list.
foreach($listObject->{'sections'} as $sectionObject) {
if ($sectionObject->{'isExpandable'}) {
$sectionToggleChecked = '';
if ($sectionObject->{'isExpandedByDefault'}) {
$sectionToggleChecked = 'checked="checked"';
}
echo '<input class="slider-list-section-toggle" id="section'.$expandSectionCounter.'-id" type="checkbox" '.$sectionToggleChecked.$
<label class="slider-list-section" for="section'.$expandSectionCounter++.'-id"> '.translate($i18n, $i18nDefault, $sectionOb$
}
echo '<div>';
// Loop over the entries of the current section.
foreach($sectionObject->{'listEntries'} as $listEntryObject) {
echo '<div class="slider-list-entry">
<div class="w-20">';
// Choose lock icon according to https or http connection.
if (substr($listEntryObject->{'href'}, 0, 5) == 'https') {
echo '<img src="'.$pathToWebFolder.'images/lock-secure.png" alt="'.translate($i18n, $i18nDefault, 'secure-alt', [], [], [])$
} else {
echo '<img src="'.$pathToWebFolder.'images/lock-insecure.png" alt="'.translate($i18n, $i18nDefault, 'insecure-alt', [], [],$
}
echo '</div>
<div class="pl-20 w-340">
[ '.htmlentities($listEntryObject->{'sourceText'}).' ]<br><a href="'.$listEntryObject->{'href'}.'">'.htmlentities($li$
</div>
</div>';
}
echo '</div>';
}
}
echo '</div>';
}
*/
// Convert the content of the links JSON file to HTML.
function addListLinks($jsonPath, $i18n, $i18nDefault) {
global $pathToWebFolder;
$expandSectionCounter = 0;
$decodedJSON = getDecodedJSON($jsonPath);
echo '<div class="slider-item slider-list">';
// Loop over the lists to display.
foreach($decodedJSON as $listObject) {
echo '<div class="slider-list-title">'.translate($i18n, $i18nDefault, $listObject->{'listTitle'}, [], [], []).'</div>';
// Loop over the sections of the current list.
foreach($listObject->{'sections'} as $sectionObject) {
if ($sectionObject->{'isExpandable'}) {
$sectionToggleChecked = '';
if ($sectionObject->{'isExpandedByDefault'}) {
$sectionToggleChecked = 'checked="checked"';
}
echo '<input class="slider-list-section-toggle" id="section'.$expandSectionCounter.'-id" type="checkbox" '.$sectionToggleChecked.'>
<label class="slider-list-section" for="section'.$expandSectionCounter++.'-id"> '.translate($i18n, $i18nDefault, $sectionObject->{'sectionTitle'}, [], [], []).'</label>';
}
echo '<div>';
// Loop over the entries of the current section.
foreach($sectionObject->{'listEntries'} as $listEntryObject) {
echo '<div class="slider-list-entry">
<div class="pl-20">
[ '.htmlentities($listEntryObject->{'sourceText'}).' ]<br><a href="'.$listEntryObject->{'href'}.'">'.htmlentities($listEntryObject->{'linkText'}).'</a>
</div>
</div>';
}
echo '</div>';
}
}
echo '</div>';
}
// Convert the content of the credits and licenses JSON file to HTML.
function addListCredits($jsonPath, $i18n, $i18nDefault) {
global $pathToWebFolder;
$decodedJSON = getDecodedJSON($jsonPath);
// Loop over the lists to display.
foreach($decodedJSON as $listObject) {
echo '<div class="slider-footer-title">'
.translate($i18n, $i18nDefault, $listObject->{'listTitle'}, [], [], []).'
</div>';
// Loop over the entries of the current list.
foreach($listObject->{'listEntries'} as $listEntryObject) {
echo '<div class="slider-credit-type">'
.translate($i18n, $i18nDefault, $listEntryObject->{'type'}, [], [], []).'
</div>';
// Loop over the credits of the current list entry.
foreach($listEntryObject->{'credits'} as $credit) {
$hrefCredit = $credit->{'href-credit'};
$hrefLicense = $credit->{'href-license'};
if (substr($hrefCredit, 0, 4) != 'http') {
$hrefCredit = $pathToWebFolder.$hrefCredit;
}
if (substr($hrefLicense, 0, 4) != 'http') {
$hrefLicense = $pathToWebFolder.$hrefLicense;
}
echo '<div>
<a href="'.$hrefCredit.'">'.htmlentities($credit->{'credit'}).'</a> [<a href="'.$hrefLicense.'">'.htmlentities($credit->{'license'}).'</a>]
</div>';
}
}
}
}
// Create a HTML list that contains the supported languages (i18n).
function addListLanguages($initialLanguage, $i18n, $i18nDefault) {
global $pathToWebFolder, $embedPerma;
$supportedLanguages = [
'de' => 'deutsch',
'en' => 'english',
'es' => 'espa&#x00F1;ol',
'fr' => 'fran&#x00E7;ais',
'it' => 'italiano',
'ru' => '&#x0440;&#x0443;&#x0441;&#x0441;&#x043A;&#x0438;&#x0439;'
];
echo '<input class="language-toggle-input" type="checkbox" id="language-id">
<label class="language-toggle-button" for="language-id">
<ul class="bar-button" id="language">
<li>
<div title="'.translate($i18n, $i18nDefault, 'language-button-alt', [], [], []).'">&nbsp;</div>
<ul>';
foreach ($supportedLanguages as $languageID => $languageDisplay) {
$classLanguangeCurrent = '';
if ($languageID == $initialLanguage) {
$classLanguangeCurrent = ' class="language-current"';
}
echo ' <a href="#" onClick="permalink(\''.$languageID.'\', '.$embedPerma.');return false;"><li'.$classLanguangeCurrent.'>'.$languageDisplay.'</li></a>';
}
echo ' </ul>
</li>
</ul>
</label>';
}
?>

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

445
www/sunders/camera.php Normal file
View file

@ -0,0 +1,445 @@
<?php
include $pathToWebFolder.'config.php';
define('MAX_POINTS_FOR_QUICKHULL', 3000);
class OsmPoint {
var $id;
var $lat;
var $lon;
function __construct($valId, $valLat, $valLon) {
$this->id = $valId;
$this->lat = $valLat;
$this->lon = $valLon;
}
}
function mergeNeighbor(&$clusterGrid, $posCell, $pos) {
global $divDiag2;
if (!array_key_exists($pos, $clusterGrid)) {
/* the neighbor is empty */
return;
}
$neighbor = $clusterGrid[$pos];
if ($neighbor['count'] == 0) {
/* The neighbor is merged to an other cell, yet */
return;
}
$cell = $clusterGrid[$posCell];
/* Calculate the (square of) distance from the cell to its neighbor */
$lonDist = ($cell['longitude']/$cell['count']) - ($neighbor['longitude']/$neighbor['count']);
$latDist = ($cell['latitude'] /$cell['count']) - ($neighbor['latitude'] /$neighbor['count']);
$dist = ($lonDist * $lonDist) + ($latDist * $latDist);
if ($dist < $divDiag2 / 10) {
$count = $cell['count'] + $neighbor['count'];
$clusterGrid[$posCell]['latitude'] = $cell['latitude'] + $neighbor['latitude'];
$clusterGrid[$posCell]['longitude'] = $cell['longitude'] + $neighbor['longitude'];
$clusterGrid[$posCell]['count'] = $count;
$clusterGrid[$posCell]['points'] = array_merge($cell['points'], $neighbor['points']);
/* Invalidate the merged neighbor */
$clusterGrid[$pos]['count'] = 0;
}
}
function mergeNeighborhood(&$clusterGrid, $pos) {
global $divWCount, $divHCount;
if ($clusterGrid[$pos]['count'] == 0) {
/* cell merged yet */
return;
}
$latLon = explode(',', $clusterGrid[$pos]['grid'] );
if ($latLon[0] > 0 && $latLon[1] < $divHCount - 1) {
if ($latLon[0] > 0) {
$posNeigh = ($latLon[0] - 1) . ',' . ($latLon[1] + 1);
mergeNeighbor($clusterGrid, $pos, $posNeigh);
}
$posNeigh = $latLon[0] . ',' . ($latLon[1] + 1);
mergeNeighbor($clusterGrid, $pos, $posNeigh);
if ($latLon[0] < $divWCount - 1) {
$posNeigh = ($latLon[0] + 1) . ',' . ($latLon[1] + 1);
mergeNeighbor($clusterGrid, $pos, $posNeigh);
}
}
if ($latLon[0] < $divWCount - 1) {
$posNeigh = ($latLon[0] + 1) . ',' . $latLon[1];
mergeNeighbor($clusterGrid, $pos, $posNeigh);
}
}
/* Recursive calculation of the quick hull algo
$isBottom : 1 if bottom point is searched, -1 if top point is searched */
function quickHullCalc(&$pointList, $count, $minPoint, $maxPoint, $isBottom) {
$msg = 'Quick count='.$count.', min=('.$minPoint->id.','.$minPoint->lat.','.$minPoint->lon.'), max=('.$minPoint->id.','.$minPoint->lat.','.$minPoint->lon.'), isBottom='.$isBottom;
$farthestPoint = null;
$farthestDist = 0;
$outsideList = array();
$outsideListCount = 0;
if ($maxPoint->lon != $minPoint->lon) {
/* Get the line equation as y = mx + p */
$m = ($maxPoint->lat - $minPoint->lat) / ($maxPoint->lon - $minPoint->lon);
$p = ($maxPoint->lat * $minPoint->lon - $minPoint->lat * $maxPoint->lon) / ($minPoint->lon - $maxPoint->lon);
} else {
/* The line equation is y = p */
$m = null;
$p = $minPoint->lat;
$coef = (($minPoint->lon > $maxPoint->lon) ? 1 : -1);
}
/* For each point, check whether :
- it is on the right side of the line
- it is the farthest from the line
*/
foreach ($pointList as $point) {
if (isset($m)) {
$dist = $isBottom * ($m * $point->lon - $point->lat + $p);
} else {
$dist = $coef * ($point->lon - $p);
}
if ($dist > 0
&& $point->id != $minPoint->id
&& $point->id != $maxPoint->id) {
array_push($outsideList, $point);
$outsideListCount++;
if ($dist > $farthestDist) {
$farthestPoint = $point;
$farthestDist = $dist;
}
}
}
if ($outsideListCount == 0) {
return array($minPoint);
} else if ($outsideListCount == 1) {
return array($minPoint, $outsideList[0]);
} else {
return array_merge(
quickHullCalc($outsideList, $outsideListCount, $minPoint, $farthestPoint, $isBottom),
quickHullCalc($outsideList, $outsideListCount, $farthestPoint, $maxPoint, $isBottom));
}
}
/* This function receives a list of points [lat, lon] and returns a list of points [lat, lon]
representing the minimal convex polygon containing the points */
function quickHull(&$pointList, $count) {
$msg= 'Quick count='.$count;
if ($count == 0) {
return array();
} else if ($count == 1) {
return array($pointList[0]);
} else if ($count == 2) {
return array($pointList[0], $pointList[1]);
}
/* retrieves the min and max points on the x axe */
$minPoint = $pointList[0];
$maxPoint = $pointList[0];
foreach ($pointList as $point) {
if ($point->lon < $minPoint->lon || ($point->lon == $minPoint->lon && $point->lat < $minPoint->lat)) {
$minPoint = $point;
}
if ($point->lon > $maxPoint->lon || ($point->lon == $maxPoint->lon && $point->lat > $maxPoint->lat)) {
$maxPoint = $point;
}
}
$bottomPoints = quickHullCalc($pointList, $count, $minPoint, $maxPoint, 1);
$topPoints = quickHullCalc($pointList, $count, $maxPoint, $minPoint, -1);
return array_merge($bottomPoints, $topPoints);
}
$GRID_MAX_ZOOM = 16;
$GRID_CELL_PIXEL = 90;
/* Check if parameters are not empty */
if ( !array_key_exists('bbox', $_GET)
|| !array_key_exists('zoom', $_GET)
|| !array_key_exists('width', $_GET)
|| !array_key_exists('height', $_GET)) {
header('Content-type: application/json');
$result = '{"error":"bbox, zoom, width and height parameters are required. '
.(array_key_exists('bbox', $_GET) ? '' : 'bbox is empty. ')
.(array_key_exists('zoom', $_GET) ? '' : 'zoom is empty. ')
.(array_key_exists('width', $_GET) ? '' : 'width is empty. ')
.(array_key_exists('height', $_GET) ? '' : 'height is empty. ')
.'"}';
echo $result;
exit;
}
/* Check zoom */
$zoom = $_GET['zoom'];
if ( !is_numeric($zoom)
|| intval($zoom) < 1
|| intval($zoom) > 19) {
header('Content-type: application/json');
$result = '{"error":"unexpected zoom value : '
.htmlentities($zoom)
.'"}';
echo $result;
exit;
}
/* Check bounds box --> bbox=boundsSW.lng,boundsSW.lat,boundsNE.lng,boundsNE.lat */
$bbox = explode(',', $_GET['bbox']);
if ( !is_numeric($bbox[0]) || $bbox[0] > 180 // 0 = SW.lng
|| !is_numeric($bbox[2]) || $bbox[2] < -180 // 2 = NE.lng
|| !is_numeric($bbox[1]) || $bbox[1] < -90 || $bbox[1] > 90 // 1 = SW.lat
|| !is_numeric($bbox[3]) || $bbox[3] < -90 || $bbox[3] > 90) { // 3 = NE.lat
header('Content-type: application/json');
$result = '{"error":"unexpected bbox longitude and latitude values : '
.'lon ['.htmlentities($bbox[0]).', '.htmlentities($bbox[2]).'], '
.'lat ['.htmlentities($bbox[1]).', '.htmlentities($bbox[3]).']'
.'"}';
echo $result;
exit;
}
if ($bbox[0] >= $bbox[2]) { // 0 = SW.lng | 2 = NE.lng
header('Content-type: application/json');
$result = '{"error":"min longitude greater than max longitude : '
.'lon ['.htmlentities($bbox[0]).', '.htmlentities($bbox[2]).']'
.'"}';
echo $result;
exit;
}
if ($bbox[1] >= $bbox[3]) { // 1 = SW.lat | 3 = NE.lat
header('Content-type: application/json');
$result = '{"error":"min latitude greater than max latitude : '
.'lat ['.htmlentities($bbox[1]).', '.htmlentities($bbox[3]).']'
.'"}';
echo $result;
exit;
}
$lonMin = $bbox[0]; // 0 = SW.lng
$lonMax = $bbox[2]; // 2 = NE.lng
$latMin = $bbox[1]; // 1 = SW.lat
$latMax = $bbox[3]; // 3 = NE.lat
$pixelWidth = (int) $_GET['width'];
$pixelHeight = (int) $_GET['height'];
if ($pixelWidth == 0 || $pixelHeight == 0) {
header('Content-type: application/json');
$result = '{"error":"width or height is null : '
.htmlentities($pixelWidth).'x'.htmlentities($pixelHeight)
.'"}';
echo $result;
exit;
}
$lonWidth = $lonMax - $lonMin; // NE.lng - SW.lng
$latHeight = $latMax - $latMin; // NE.lat - SW.lat
$divWCount = ((int) ($pixelWidth / $GRID_CELL_PIXEL)) + 1;
$divHCount = ((int) ($pixelHeight / $GRID_CELL_PIXEL)) + 1;
$divWidth = $lonWidth / $divWCount;
$divHeight = $latHeight / $divHCount;
$divDiag2 = ($divWidth * $divWidth) + ($divHeight * $divHeight);
/* Connect to database */
$mysqli = new mysqli(MYSQL_HOST, MYSQL_USER, MYSQL_PASSWD, MYSQL_DB);
if($mysqli->connect_errno) {
header('Content-type: application/json');
$result = '{"error":"error while connecting to db : ' . $mysqli->error . '"}';
echo $result;
exit;
}
$rqtLonMin = $lonMin; // SW.lng
$rqtLonMax = $lonMax; // NE.lng
/* Indicates whether the map displays the -180/180° longitude */
if ($rqtLonMax - $rqtLonMin > 360) {
$rqtLonMin = -180;
$rqtLonMax = 180;
}
/* Select the nodes to be returned, and cluster them on a grid if necessary */
if ($rqtLonMin >= -180 && $lonMax <= 180) {
$sql='SELECT id, latitude, longitude
FROM position
WHERE latitude between ? and ?
AND longitude between ? and ?';
} else {
$sql='SELECT id, latitude, longitude
FROM position
WHERE latitude between ? and ?
AND (longitude between ? and 1800000000 OR longitude between -1800000000 and ?)';
while ($rqtLonMin < -180) {
$rqtLonMin += 360;
}
while ($rqtLonMax > 180) {
$rqtLonMax -= 360;
}
}
$rqtLonMin = bcmul($rqtLonMin, 10000000, 0); // SW.lng
$rqtLonMax = bcmul($rqtLonMax, 10000000, 0); // NE.lng
$rqtLatMin = bcmul($latMin, 10000000, 0); // SW.lat
$rqtLatMax = bcmul($latMax, 10000000, 0); // NE.lat
$resArray = array();
$nbFetch = 0;
if ($stmt = $mysqli->prepare($sql)) {
$stmt->bind_param('iiii', $rqtLatMin, $rqtLatMax, $rqtLonMin, $rqtLonMax); // SW.lat, NE.lat, SW.lng, NE.lng
$stmt->execute();
$stmt->bind_result($id, $latitude, $longitude);
while ($stmt->fetch()) {
$nbFetch++;
$latitude = bcdiv($latitude, 10000000, 7);
$longitude = bcdiv($longitude, 10000000, 7);
while ($longitude < $lonMin) { // $lonMin = SW.lng
$longitude += 360;
}
while ($longitude > $lonMax) { // $lonMax = NE.lng
$longitude -= 360;
}
/* Initialize the current point */
if ($zoom >= $GRID_MAX_ZOOM) {
array_push($resArray, array(
'points' => array(new OsmPoint($id, $latitude, $longitude)),
'latitude' => $latitude,
'longitude' => $longitude,
'count' => 1 ));
} else {
$posLat = (int) (($latitude - $latMin) / $divHeight); // $latMin = SW.lat
$posLon = (int) (($longitude - $lonMin) / $divWidth); // $lonMin = SW.lng
$pos = $posLon.','.$posLat;
if (!array_key_exists($pos, $resArray)) {
$resArray[$pos] = array(
'points' => array(),
'latitude' => 0,
'longitude' => 0,
'count' => 0,
'grid' => $pos);
}
$elt = new OsmPoint($id, $latitude, $longitude);
array_push($resArray[$pos]['points'], $elt);
/* Increment the number of points */
$resArray[$pos]['count']++;
$resArray[$pos]['latitude'] += $latitude;
$resArray[$pos]['longitude'] += $longitude;
}
}
$stmt->close();
} else {
$mysqli->close();
header('Content-type: application/json');
$result = '{"error":"Error while request : ' . $mysqli->error . '"}';
echo $result;
exit;
}
/* Unify some clusters if nodes center are near */
$pointsCount = 0;
if ($zoom < $GRID_MAX_ZOOM) {
foreach($resArray as $val) {
mergeNeighborhood($resArray, $val['grid']);
$pointsCount += $val['count'];
}
}
$result='[';
$separator='';
/* Writing selected points */
$sql='SELECT k, v
FROM tag
WHERE id = ?
AND k NOT IN ("lat", "lon")';
$stmt = $mysqli->prepare($sql);
$stmt->bind_param('d', $id);
$stmt->bind_result($k, $v);
/* Writing grouped items or not */
foreach($resArray as $val) {
if ($val['count'] > 0) {
$result = $result.$separator
.'{"lat":"'.($val['latitude'] / $val['count']).'"'
.',"lon":"'.($val['longitude'] / $val['count']).'"';
if ($val['count'] == 1) {
$id = $val['points'][0]->id;
$result = $result.',"id":"'.$id.'"';
$stmt->execute();
while($stmt->fetch()) {
$result = $result.',"'.htmlentities($k).'":"'.htmlentities($v, ENT_COMPAT, 'UTF-8').'"';
}
} else {
$result = $result
.',"count":"'.$val['count'].'"'
.',"multi":"yes"'
.',"poly":[';
if ($pointsCount < MAX_POINTS_FOR_QUICKHULL) {
$convexPoly = quickHull($val['points'], $val['count']);
$sepPoly = '';
foreach($convexPoly as $point) {
$result = $result.$sepPoly.'{'
.'"lat":"'.$point->lat.'"'
.',"id":"'.$point->id.'"'
.',"lon":"'.$point->lon.'"}';
$sepPoly=',';
}
}
$result=$result.']';
}
$result = $result.'}';
$separator=',';
}
}
$stmt->close();
$result = $result . ']';
$mysqli->close();
header('Content-type: application/json; Charset : utf-8');
echo $result;
?>

View file

@ -0,0 +1,17 @@
<?php
define('DEFAULT_ZOOM', 15);
define('DEFAULT_LAT', 52.37672572);
define('DEFAULT_LON', 9.73787785);
define('DEFAULT_LANGUAGE', 'en');
define('DEFAULT_PIE', 'country');
define('DEFAULT_TIME', 'single');
define('MYSQL_HOST', 'localhost');
define('MYSQL_DB', 'camera');
define('MYSQL_USER', 'camselect');
define('MYSQL_PASSWD', null);
define('USE_STATISTICS', false);
?>

179
www/sunders/css/spinner.css Normal file
View file

@ -0,0 +1,179 @@
.spinner-bar {
display: flex;
justify-content: space-between;
width: 360px;
}
@keyframes spinner1 {
0% { opacity: 1; }
5% { opacity: 1; }
10% { opacity: 0.2; }
90% { opacity: 0.2; }
95% { opacity: 1; }
100% { opacity: 1; }
}
@keyframes spinner2 {
0% { opacity: 0.2; }
5% { opacity: 1; }
10% { opacity: 1; }
15% { opacity: 0.2; }
85% { opacity: 0.2; }
90% { opacity: 1; }
95% { opacity: 1; }
100% { opacity: 0.2; }
}
@keyframes spinner3 {
0% { opacity: 0.2; }
5% { opacity: 0.2; }
10% { opacity: 1; }
15% { opacity: 1; }
20% { opacity: 0.2; }
80% { opacity: 0.2; }
85% { opacity: 1; }
90% { opacity: 1; }
95% { opacity: 0.2; }
100% { opacity: 0.2; }
}
@keyframes spinner4 {
0% { opacity: 0.2; }
10% { opacity: 0.2; }
15% { opacity: 1; }
20% { opacity: 1; }
25% { opacity: 0.2; }
75% { opacity: 0.2; }
80% { opacity: 1; }
85% { opacity: 1; }
90% { opacity: 0.2; }
100% { opacity: 0.2; }
}
@keyframes spinner5 {
0% { opacity: 0.2; }
15% { opacity: 0.2; }
20% { opacity: 1; }
25% { opacity: 1; }
30% { opacity: 0.2; }
70% { opacity: 0.2; }
75% { opacity: 1; }
80% { opacity: 1; }
85% { opacity: 0.2; }
100% { opacity: 0.2; }
}
@keyframes spinner6 {
0% { opacity: 0.2; }
20% { opacity: 0.2; }
25% { opacity: 1; }
30% { opacity: 1; }
35% { opacity: 0.2; }
65% { opacity: 0.2; }
70% { opacity: 1; }
75% { opacity: 1; }
80% { opacity: 0.2; }
100% { opacity: 0.2; }
}
@keyframes spinner7 {
0% { opacity: 0.2; }
25% { opacity: 0.2; }
30% { opacity: 1; }
35% { opacity: 1; }
40% { opacity: 0.2; }
60% { opacity: 0.2; }
65% { opacity: 1; }
70% { opacity: 1; }
75% { opacity: 0.2; }
100% { opacity: 0.2; }
}
@keyframes spinner8 {
0% { opacity: 0.2; }
30% { opacity: 0.2; }
35% { opacity: 1; }
40% { opacity: 1; }
45% { opacity: 0.2; }
55% { opacity: 0.2; }
60% { opacity: 1; }
65% { opacity: 1; }
70% { opacity: 0.2; }
100% { opacity: 0.2; }
}
@keyframes spinner9 {
0% { opacity: 0.2; }
35% { opacity: 0.2; }
40% { opacity: 1; }
45% { opacity: 1; }
50% { opacity: 0.2; }
55% { opacity: 1; }
60% { opacity: 1; }
65% { opacity: 0.2; }
100% { opacity: 0.2; }
}
@keyframes spinner10 {
0% { opacity: 0.2; }
40% { opacity: 0.2; }
45% { opacity: 1; }
55% { opacity: 1; }
60% { opacity: 0.2; }
100% { opacity: 0.2; }
}
.spinner {
animation-duration: 2s;
animation-iteration-count: infinite;
animation-direction: alternate;
}
.spinner1 {
animation-name: spinner1;
}
.spinner2 {
animation-name: spinner2;
}
.spinner3 {
animation-name: spinner3;
}
.spinner4 {
animation-name: spinner4;
}
.spinner5 {
animation-name: spinner5;
}
.spinner6 {
animation-name: spinner6;
}
.spinner7 {
animation-name: spinner7;
}
.spinner8 {
animation-name: spinner8;
}
.spinner9 {
animation-name: spinner9;
}
.spinner10 {
animation-name: spinner10;
}
/* MOBILE SETTINGS */
@media only screen and (max-width: 600px) {
.spinner-bar {
width: 100%;
padding-right: 20px;
padding-left: 20px;
}
}

588
www/sunders/css/stats.css Normal file
View file

@ -0,0 +1,588 @@
/* ICON COLORS */
.icon0-color { color: #6c5d53; } /* gray */
.icon1-color { color: #d40055; } /* red */
.icon2-color { color: #0055d4; } /* blue */
.icon3-color { color: #00d455; } /* green */
.iconxxx-color { color: #a1a1b3; } /* text color */
/* ICON FILL COLORS */
.icon0-fill { fill: #6c5d53; } /* gray */
.icon1-fill { fill: #d40055; } /* red */
.icon2-fill { fill: #0055d4; } /* blue */
.icon3-fill { fill: #00d455; } /* green */
.iconxxx-fill { fill: #a1a1b3; } /* text color */
/* ICON STROKE COLORS */
.icon0-stroke { stroke: #6c5d53; } /* gray */
.icon1-stroke { stroke: #d40055; } /* red */
.icon2-stroke { stroke: #0055d4; } /* blue */
.icon3-stroke { stroke: #00d455; } /* green */
.iconxxx-stroke { stroke: #a1a1b3; } /* text color */
/* ICON BACKGROUND COLORS */
.icon0-bg { background: #6c5d53; } /* gray */
.icon1-bg { background: #d40055; } /* red */
.icon2-bg { background: #0055d4; } /* blue */
.icon3-bg { background: #00d455; } /* green */
.iconxxx-bg { background: #a1a1b3; } /* text color */
/* ICON BORDER TOP COLORS */
.icon0-bt { border-top: 1px solid #6c5d53; } /* gray */
.icon1-bt { border-top: 1px solid #d40055; } /* red */
.icon2-bt { border-top: 1px solid #0055d4; } /* blue */
.icon3-bt { border-top: 1px solid #00d455; } /* green */
.iconxxx-bt { border-top: 1px solid #a1a1b3; } /* text color */
/* ICON BORDER BOTTOM COLORS */
.icon0-bb { border-bottom: 1px solid #6c5d53; } /* gray */
.icon1-bb { border-bottom: 1px solid #d40055; } /* red */
.icon2-bb { border-bottom: 1px solid #0055d4; } /* blue */
.icon3-bb { border-bottom: 1px solid #00d455; } /* green */
.iconxxx-bb { border-bottom: 1px solid #a1a1b3; } /* text color */
/* CHART COLORS */
.color0-color { color: #6c5d53; } /* gray */
.color1-color { color: rgb(117, 60,123); }
.color2-color { color: rgb(179,121,216); }
.color3-color { color: rgb(202, 45,197); }
.color4-color { color: rgb(170, 0,120); }
.color5-color { color: rgb(209, 15, 85); }
.color6-color { color: rgb(236, 75, 24); }
.color7-color { color: rgb(247,147, 30); }
.color8-color { color: rgb(252,226,108); }
.color9-color { color: rgb(198,242, 94); }
.color10-color { color: rgb(159,196, 55); }
.color11-color { color: rgb( 87,226, 76); }
.color12-color { color: rgb( 64,164, 66); }
.color13-color { color: rgb( 5,222,158); }
.color14-color { color: rgb(196,252,240); }
.color15-color { color: rgb(100,186,170); }
.color16-color { color: rgb( 45,166,162); }
.color17-color { color: rgb( 26,167,238); }
.color18-color { color: rgb( 93,102,232); }
.color19-color { color: rgb( 53, 60,152); }
.color20-color { color: rgb( 53, 11,122); }
.colorxxx-color { color: #a1a1b3; } /* text color */
/* CHART FILL COLORS */
.color0-fill { fill: #6c5d53; } /* gray */
.color1-fill { fill: rgb(117, 60,123); }
.color2-fill { fill: rgb(179,121,216); }
.color3-fill { fill: rgb(202, 45,197); }
.color4-fill { fill: rgb(170, 0,120); }
.color5-fill { fill: rgb(209, 15, 85); }
.color6-fill { fill: rgb(236, 75, 24); }
.color7-fill { fill: rgb(247,147, 30); }
.color8-fill { fill: rgb(252,226,108); }
.color9-fill { fill: rgb(198,242, 94); }
.color10-fill { fill: rgb(159,196, 55); }
.color11-fill { fill: rgb( 87,226, 76); }
.color12-fill { fill: rgb( 64,164, 66); }
.color13-fill { fill: rgb( 5,222,158); }
.color14-fill { fill: rgb(196,252,240); }
.color15-fill { fill: rgb(100,186,170); }
.color16-fill { fill: rgb( 45,166,162); }
.color17-fill { fill: rgb( 26,167,238); }
.color18-fill { fill: rgb( 93,102,232); }
.color19-fill { fill: rgb( 53, 60,152); }
.color20-fill { fill: rgb( 53, 11,122); }
.colorxxx-fill { fill: #a1a1b3; } /* text color */
/* CHART STROKE COLORS */
.color0-stroke { stroke: #6c5d53; } /* gray */
.color1-stroke { stroke: rgb(117, 60,123); }
.color2-stroke { stroke: rgb(179,121,216); }
.color3-stroke { stroke: rgb(202, 45,197); }
.color4-stroke { stroke: rgb(170, 0,120); }
.color5-stroke { stroke: rgb(209, 15, 85); }
.color6-stroke { stroke: rgb(236, 75, 24); }
.color7-stroke { stroke: rgb(247,147, 30); }
.color8-stroke { stroke: rgb(252,226,108); }
.color9-stroke { stroke: rgb(198,242, 94); }
.color10-stroke { stroke: rgb(159,196, 55); }
.color11-stroke { stroke: rgb( 87,226, 76); }
.color12-stroke { stroke: rgb( 64,164, 66); }
.color13-stroke { stroke: rgb( 5,222,158); }
.color14-stroke { stroke: rgb(196,252,240); }
.color15-stroke { stroke: rgb(100,186,170); }
.color16-stroke { stroke: rgb( 45,166,162); }
.color17-stroke { stroke: rgb( 26,167,238); }
.color18-stroke { stroke: rgb( 93,102,232); }
.color19-stroke { stroke: rgb( 53, 60,152); }
.color20-stroke { stroke: rgb( 53, 11,122); }
.colorxxx-stroke { stroke: #a1a1b3; } /* text color */
/* CHART BACKGROUD COLORS */
.color0-bg { background: #6c5d53; } /* gray */
.color1-bg { background: rgb(117, 60,123); }
.color2-bg { background: rgb(179,121,216); }
.color3-bg { background: rgb(202, 45,197); }
.color4-bg { background: rgb(170, 0,120); }
.color5-bg { background: rgb(209, 15, 85); }
.color6-bg { background: rgb(236, 75, 24); }
.color7-bg { background: rgb(247,147, 30); }
.color8-bg { background: rgb(252,226,108); }
.color9-bg { background: rgb(198,242, 94); }
.color10-bg { background: rgb(159,196, 55); }
.color11-bg { background: rgb( 87,226, 76); }
.color12-bg { background: rgb( 64,164, 66); }
.color13-bg { background: rgb( 5,222,158); }
.color14-bg { background: rgb(196,252,240); }
.color15-bg { background: rgb(100,186,170); }
.color16-bg { background: rgb( 45,166,162); }
.color17-bg { background: rgb( 26,167,238); }
.color18-bg { background: rgb( 93,102,232); }
.color19-bg { background: rgb( 53, 60,152); }
.color20-bg { background: rgb( 53, 11,122); }
.colorxxx-bg { background: #a1a1b3; } /* text color */
/* CHART BORDER TOP COLORS */
.color0-bt { border-top: 1px solid #6c5d53; } /* gray */
.color1-bt { border-top: 1px solid rgb(117, 60,123); }
.color2-bt { border-top: 1px solid rgb(179,121,216); }
.color3-bt { border-top: 1px solid rgb(202, 45,197); }
.color4-bt { border-top: 1px solid rgb(170, 0,120); }
.color5-bt { border-top: 1px solid rgb(209, 15, 85); }
.color6-bt { border-top: 1px solid rgb(236, 75, 24); }
.color7-bt { border-top: 1px solid rgb(247,147, 30); }
.color8-bt { border-top: 1px solid rgb(252,226,108); }
.color9-bt { border-top: 1px solid rgb(198,242, 94); }
.color10-bt { border-top: 1px solid rgb(159,196, 55); }
.color11-bt { border-top: 1px solid rgb( 87,226, 76); }
.color12-bt { border-top: 1px solid rgb( 64,164, 66); }
.color13-bt { border-top: 1px solid rgb( 5,222,158); }
.color14-bt { border-top: 1px solid rgb(196,252,240); }
.color15-bt { border-top: 1px solid rgb(100,186,170); }
.color16-bt { border-top: 1px solid rgb( 45,166,162); }
.color17-bt { border-top: 1px solid rgb( 26,167,238); }
.color18-bt { border-top: 1px solid rgb( 93,102,232); }
.color19-bt { border-top: 1px solid rgb( 53, 60,152); }
.color20-bt { border-top: 1px solid rgb( 53, 11,122); }
.colorxxx-bt { border-top: 1px solid #a1a1b3; } /* text color */
/* CHART BORDER BOTTOM COLORS */
.color0-bb { border-bottom: 1px solid #6c5d53; } /* gray */
.color1-bb { border-bottom: 1px solid rgb(117, 60,123); }
.color2-bb { border-bottom: 1px solid rgb(179,121,216); }
.color3-bb { border-bottom: 1px solid rgb(202, 45,197); }
.color4-bb { border-bottom: 1px solid rgb(170, 0,120); }
.color5-bb { border-bottom: 1px solid rgb(209, 15, 85); }
.color6-bb { border-bottom: 1px solid rgb(236, 75, 24); }
.color7-bb { border-bottom: 1px solid rgb(247,147, 30); }
.color8-bb { border-bottom: 1px solid rgb(252,226,108); }
.color9-bb { border-bottom: 1px solid rgb(198,242, 94); }
.color10-bb { border-bottom: 1px solid rgb(159,196, 55); }
.color11-bb { border-bottom: 1px solid rgb( 87,226, 76); }
.color12-bb { border-bottom: 1px solid rgb( 64,164, 66); }
.color13-bb { border-bottom: 1px solid rgb( 5,222,158); }
.color14-bb { border-bottom: 1px solid rgb(196,252,240); }
.color15-bb { border-bottom: 1px solid rgb(100,186,170); }
.color16-bb { border-bottom: 1px solid rgb( 45,166,162); }
.color17-bb { border-bottom: 1px solid rgb( 26,167,238); }
.color18-bb { border-bottom: 1px solid rgb( 93,102,232); }
.color19-bb { border-bottom: 1px solid rgb( 53, 60,152); }
.color20-bb { border-bottom: 1px solid rgb( 53, 11,122); }
.colorxxx-bb { border-bottom: 1px solid #a1a1b3; } /* text color */
body {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
background: #222233;
color: #a1a1b3;
font-family: sans-serif;
}
.light {
font-weight: 100;
}
.bold {
font-weight: bold;
}
.right {
text-align: right;
}
text {
fill: #a1a1b3;
}
a {
color: #0192d9;
text-decoration: none;
}
a:hover {
color: #a1a1b3;
}
a text {
fill: #0192d9;
}
div.selected {
border-bottom: solid 2px #0192d9;
}
div.unselected {
border-bottom: solid 2px #222233;
}
.header, .footer {
text-align: center;
margin: 0 10%;
}
.header:hover, .footer:hover {
background: rgba(161, 161, 179, 0.2);
}
.header {
margin-top: 60px;
}
.footer {
margin-bottom: 60px;
}
.distance {
margin: 0 10% 3% 10%;
}
.to-be-translated {
color: #d40055;
}
.to-be-translated a {
color: #ac39ac;
text-decoration: none;
}
.to-be-translated a:hover {
color: #d40055;
}
@media (orientation: landscape) {
.pie {
flex-direction: row;
}
.pie .pie-chart {
width: 50%;
}
.pie .pie-legend {
width: 40%;
padding-left: 10%;
}
}
@media (orientation: portrait) {
.pie {
flex-direction: column;
}
.pie > div {
width: 100%;
}
.pie .pie-legend {
margin-top: 50px;
}
}
/* TOTAL CHART */
.vb-total {
margin: 10%;
}
.g-total > text {
text-anchor: middle;
}
.g-total .number {
font-size: 20px;
}
.g-total .text {
font-size: 3px;
}
/* NAVI */
.navi-section-check {
display: none;
}
.navi-section-check + .navi-section-toggle {
cursor: pointer;
display: block;
}
/* checkbox = false --> hide navi section */
.navi-section-check ~ .navi-section {
display: none;
}
/* checkbox = true --> hide toggle button */
.navi-section-check:checked + .navi-section-toggle {
display: none;
}
/* checkbox = true --> show navi section */
.navi-section-check:checked ~ .navi-section {
display: block;
}
.navi-section-toggle {
margin: 0 10%;
}
.navi-section-toggle:hover {
background: rgba(161, 161, 179, 0.2);
}
.navi-section-toggle .navi-text {
fill: #0192d9;
font-size: 3px;
}
.navi-row {
display: flex;
flex-direction: row;
margin: 0 10%;
}
.navi-row.cats .navi-text {
font-size: 10px;
}
.navi-row.years .navi-text, .navi-row.months .navi-text {
font-size: 17px;
}
.navi-row.lines .navi-text {
font-size: 6.5px;
}
.navi-element:hover {
background: rgba(161, 161, 179, 0.2);
}
.navi-text {
text-anchor: middle;
font-weight: lighter;
}
/* PIE CHART */
.pie {
display: flex;
align-items: flex-start;
margin: 10%;
}
.pie-slice-link {
cursor: pointer;
}
.pie-text {
text-anchor: middle;
font-size: 6px;
}
.g-pie path {
stroke: #222233;
}
.g-pie .donut-hole {
fill: #222233;
}
.pie-legend-row {
margin-bottom: 10px;
}
.pie-legend-row > div {
display: flex;
flex-direction: row;
}
.square {
min-width: 20px;
min-height: 20px;
}
.square-double {
min-width: 40px;
min-height: 20px;
}
/* PIE CHART LEGEND */
.pie-legend-section-check {
display: none;
}
/* checkbox = false
-- show section 'less'
-- show button 'more'
-- hide section 'more'
-- hide button 'less' */
.pie-legend-section-check ~ .pie-legend-less {
display: block;
}
.pie-legend-section-check ~ .pie-legend-section-toggle-more {
display: block;
}
.pie-legend-section-check ~ .pie-legend-more {
display: none;
}
.pie-legend-section-check ~ .pie-legend-section-toggle-less {
display: none;
}
/* checkbox = true
-- show section 'more'
-- show button 'less'
-- hide section 'less'
-- hide button 'more' */
.pie-legend-section-check:checked ~ .pie-legend-more {
display: block;
}
.pie-legend-section-check:checked ~ .pie-legend-section-toggle-less {
display: block;
}
.pie-legend-section-check:checked ~ .pie-legend-less {
display: none;
}
.pie-legend-section-check:checked ~ .pie-legend-section-toggle-more {
display: none;
}
.pie-legend label {
cursor: pointer;
height: 40px;
background-repeat: no-repeat;
background-position: 40px;
background-color: transparent;
}
.pie-legend-section-toggle-more {
background-image: url('../images/button_more_blue.png');
}
.pie-legend-section-toggle-more:hover {
background-image: url('../images/button_more_gray.png');
}
.pie-legend-section-toggle-less {
background-image: url('../images/button_less_blue.png');
}
.pie-legend-section-toggle-less:hover {
background-image: url('../images/button_less_gray.png');
}
/* TIME CHART */
.time {
display: flex;
flex-direction: column;
margin: 10%;
}
.time-chart {
margin-bottom: 50px;
}
.line-text {
text-anchor: middle;
font-weight: lighter;
}
.g-time {
fill: none;
stroke-width: 4px;
}
.day .g-time {
stroke-width: 10px;
}
.h-grid, .v-grid {
stroke: #a1a1b3;
}
.h-grid {
stroke-width: 2px;
stroke-opacity: 0.1;
}
.v-grid {
stroke-dasharray:0.5%, 1%;
stroke-opacity: 0.2;
}
.day .h-grid {
stroke-width: 5px;
}
.day .v-grid {
stroke-width: 3px;
}
.v-label {
text-anchor: middle;
}
.time-legend table {
width: 100%;
border-collapse: collapse;
}
.time-legend .title {
padding-bottom: 50px;
text-align: center;
font-size: 1.2rem;
}
.time .row-distance {
font-size: 0.2rem;
}
.time .row-title {
font-size: 0.8rem;
}
tfoot td {
font-weight: bold;
text-align: center;
padding-top: 8px;
}
/*.even-bg {
background: rgba(161, 161, 179, 0.1);
}*/

766
www/sunders/css/sunders.css Normal file
View file

@ -0,0 +1,766 @@
/* COLORS
background: #222233 / 34, 34, 51
text: #a1a1b3 / 161,161,179
links: #0192d9 / 1,146,217
beige: #f1eee8 / 241,238,232
lightblue: #0192d9 / 1,146,217
darkblue: #050585 / 5, 5,133
gray: #d9d0c9 / 217,208,201
purple: #ac39ac / 172, 57,172
red icon: #d40055 / 212, 0, 85
blue icon: #0055d4 / 0, 85,212
green icon: #00d455 / 0,212, 85
gray icon: #6c5d53 / 108, 93, 83
yellow icon: #ffdd55 / 255,221, 85 */
html {
height: 100%;
}
body {
height: 100%;
margin: 0;
padding: 0;
overflow-x: hidden;
font-family: sans-serif;
}
#map {
width: 100%;
height: 100%;
}
.bold {
font-weight: bold;
}
.monospace {
font-family: monospace;
font-size: 1.5em;
}
.text-small {
font-size: 0.8em;
}
.text-medium {
font-size: 0.9em;
}
.w-20 {
width: 20px;
}
.w-45 {
width: 45px;
min-width: 45px;
}
.w-120 {
width: 120px;
min-width: 120px;
}
.w-240 {
width: 240px;
}
.w-260 {
width: 260px;
}
.w-315 {
width: 315px;
}
.w-340 {
width: 340px;
}
.pl-20 {
padding-left: 20px;
}
.slider-toggle-input[type=checkbox] {
position: absolute;
opacity: 0;
}
.slider-toggle-input[type=checkbox]:checked ~ .slider-overlay,
.slider-toggle-input[type=checkbox]:checked ~ .slider {
transform: translate3d(0, 0, 0);
}
.slider-toggle-input[type=checkbox]:checked ~ .slider-toggle-button {
transform: translate3d(-490px, 0, 0) rotate(180deg);
}
.slider-toggle-button {
position: absolute;
top: 10px;
right: 10px;
z-index: 250000;
cursor: pointer;
transform-origin: 20px 20px;
transition: transform .8s;
}
.slider-toggle-bar {
display: none;
}
.slider-overlay {
position: absolute;
right: 30px;
width: 470px;
z-index: 200000;
transform: translate3d(490px, 0, 0);
transition: all .8s;
}
/*#news.slider-overlay {
display: flex;
align-items: flex-end;
top: 95px;
right: -255px;
color: #ffdd55;
font-weight: bold;
}
#news.slider-overlay .text {
padding-left: 10px;
}*/
#anchorbar.slider-overlay {
top: 10px;
}
#buttonbar.slider-overlay {
top: 52px;
}
.topbar {
display: flex;
justify-content: space-around;
align-items: center;
position: absolute;
width: 470px;
height: 40px;
background: #0192d9;
color: #f1eee8;
}
.topbar.anchorbar {
background-color: rgba(1, 146, 217, 0.9);
}
.topbar.buttonbar {
background-color: rgba(1, 146, 217, 0.6);
}
.mobile-bar-padding {
width: 0;
}
.bar-button {
width: 80px;
height: 30px;
background-repeat: no-repeat;
background-position: center;
background-color: transparent;
border: 1px solid transparent;
cursor: pointer;
}
.bar-button:hover {
border: 1px solid #f1eee8;
}
.bar-button.main {
width: 120px;
}
.bar-button.search {
background-image: url('../images/button_search.png');
}
.bar-button.stats {
background-image: url('../images/button_stats.png');
}
.bar-button.permalink {
background-image: url('../images/button_permalink.png');
}
.search-group {
position: relative;
}
#search-overlay {
display: none;
position: absolute;
top: 42px;
width: 430px;
padding: 30px 20px;
background-color: rgba(1, 146, 217, 0.9);
color: #f1eee8;
}
.search-field-row {
display: flex;
justify-content: center;
align-items: center;
}
#search-input {
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
background-color: #222233;
border: 1px solid #f1eee8;
border-radius: 0px;
border-right: none;
color: #f1eee8;
width: 320px;
height: 30px;
line-height: 30px;
padding: 0px 10px;
font-family: monospace;
font-weight: bold;
}
#search-input:focus {
outline: 0;
}
.search-button {
width: 34px;
height: 32px;
background-image: url('../images/button_search.png');
background-repeat: no-repeat;
background-position: center;
background-color: #222233;
border: 1px solid #f1eee8;
border-left: 1px solid transparent;
color: #f1eee8;
cursor: pointer;
}
.search-button:hover {
border-left: 1px solid #f1eee8;
}
.search-button:focus {
outline: 0;
}
#search-results-overlay {
display: none;
position: absolute;
top: 136px;
bottom: 0;
width: 470px;
overflow-y: auto;
background: #0192d9;
background-color: rgba(1, 146, 217, 0.9);
color: #f1eee8;
}
#search-spinner-block {
display: none;
padding: 20px 0;
}
#search-spinner {
display: flex;
justify-content: center;
}
#search-results-list-block {
display: none;
padding: 20px 0;
}
#search-results-list {
display: flex;
flex-direction: column;
align-items: center;
}
.search-result {
width: 370px;
padding: 15px 20px;
border: 1px solid transparent;
border-bottom: 1px dotted #f1eee8;
line-height: 25px;
cursor: pointer;
}
.search-result:first-child {
border-top: 1px dotted #f1eee8;
}
.search-result:hover {
background-color: #222233;
}
.search-more {
width: 100px;
height: 30px;
background-repeat: no-repeat;
background-position: center;
background-color: transparent;
border: 1px solid transparent;
cursor: pointer;
}
.search-more:hover {
border: 1px solid #f1eee8;
}
.search-more.search-previous {
background-image: url('../images/button_previous.png');
margin-bottom: 10px;
}
.search-more.search-next {
background-image: url('../images/button_next.png');
margin-top: 10px;
}
.close {
position: absolute;
top: 10px;
right: 10px;
width: 20px;
height: 20px;
background-image: url('../images/close.png');
background-repeat: no-repeat;
background-position: center;
background-color: transparent;
border: 1px solid transparent;
cursor: pointer;
}
.close:hover {
border: 1px solid #f1eee8;
}
.language-toggle-input {
display: none;
}
.language-toggle-input[type=checkbox]:checked ~ .language-toggle-button #language li ul {
display: block;
}
#language {
background-image: url('../images/button_language.png');
list-style:none;
padding: 0;
z-index: 300000;
}
#language li {
position: relative;
text-align: center;
}
#language ul {
display: none;
list-style: none;
position: absolute;
padding: 0;
}
#language ul a {
color: #f1eee8;
font-family: monospace;
font-size: 1em;
text-decoration: none;
}
#language ul li {
width: 80px;
height: 30px;
line-height: 30px;
margin-top: 2px;
background-color: rgba(1, 146, 217, 0.9);
border: 1px solid #f1eee8;
}
#language ul a:first-child li {
margin-top: 18px;
}
#language ul li:hover {
background-color: rgba(1, 146, 217, 0.6);
}
.language-current {
font-weight: bold;
}
.slider {
display: flex;
flex-direction: column;
position: absolute;
top: 0px;
right: 0px;
width: 500px;
height: 100%;
z-index: 100000;
background: #f1eee8;
background-color: rgba(34, 34, 51, 0.95);
color: #a1a1b3;
overflow-y: auto;
transform: translate3d(490px, 0, 0);
transition: all .8s;
}
.slider a {
color: #0192d9;
text-decoration: none;
}
.slider a:hover {
color: #a1a1b3;
}
.slider-item {
box-sizing: border-box;
flex-shrink: 0;
padding-left: 40px;
padding-right: 40px;
}
.slider-logo {
padding: 140px 0 20px 0;
}
.slider-logo img {
display: block;
margin: 0 auto;
}
.slider-title {
padding-top: 120px;
padding-bottom: 20px;
padding-left: 40px;
}
.slider-subtitle {
text-align: center;
}
.slider-translation {
text-align: center;
font-style: italic;
padding: 20px 40px 0 40px;
}
.slider-list-title {
padding-top: 40px;
padding-bottom: 20px;
padding-left: 20px;
font-weight: bold;
}
.text-small .slider-list-title {
font-size: 1.25em;
}
.slider-list-section {
padding-left: 20px;
font-weight: bold;
font-size: 0.9em;
}
.slider-list-section-toggle {
display: none;
}
.slider-list-section-toggle + .slider-list-section {
cursor: pointer;
display: block;
font-weight: bold;
margin-top: 10px;
}
.slider-list-section-toggle + .slider-list-section + div {
display: none;
}
.slider-list-section-toggle:checked + .slider-list-section + div {
display: block;
}
.slider-list-section-toggle + .slider-list-section:before {
content: "\002B\2000"; /*plus icon + whitespace*/
display: block;
float: left;
}
.slider-list-section-toggle:checked + .slider-list-section:before {
content: "\2212\2000"; /*minus icon + whitespace*/
}
.slider-list-entry {
display: flex;
flex-direction: row;
align-items: flex-start;
padding-top: 10px;
padding-left: 20px;
}
.example-boxes {
display: flex;
flex-direction: row;
width: 100%;
}
.example-boxes .example-box {
display: flex;
flex-direction: column;
align-items: center;
width: 100%;
}
.example-boxes .example-box .example-box-image {
border: 1px solid #a1a1b3;
margin: 5px;
padding: 5px;
}
.example-boxes .example-box .example-box-description {
margin: 10px;
}
.slider-footer {
padding-top: 40px;
padding-bottom: 40px;
text-align: center;
}
.slider-footer-title {
font-weight: bold;
padding-bottom: 10px;
}
.slider-credit-type {
padding-top: 6px;
}
.slider-onion-link {
padding-top: 6px;
font-size: 1.5em;
}
/* MOBILE SETTINGS */
@media only screen and (max-width: 600px) {
.slider,
.slider-item,
.slider-list-entry .fieldofview,
.slider-overlay,
.slider-toggle-bar,
.topbar,
.w-240,
.w-260,
.w-315,
.w-340 {
width: 100%;
}
.slider-toggle-button {
display: none;
}
.slider-toggle-bar {
display: inherit;
}
.slider-overlay {
right: 0;
}
.slider-toggle-bar {
position: absolute;
bottom: 16px;
z-index: 250000;
cursor: pointer;
background-color: rgba(1, 146, 217, 0.6);
line-height: 40px;
text-align: center;
font-weight: bold;
color: #f1eee8;
}
.slider-toggle-bar.toggle-false {
display: none;
}
.slider-toggle-input[type=checkbox]:not(:checked) ~ .slider-overlay {
width: 470px;
right: 20px;
}
.slider-toggle-input[type=checkbox]:not(:checked) ~ .slider-toggle-bar.toggle-false {
display: inherit;
}
.slider-toggle-input[type=checkbox]:not(:checked) ~ .slider-toggle-bar.toggle-true {
display: none;
}
.topbar {
position: inherit;
}
.slider {
transform: translate3d(500px, 0, 0);
}
.slider-toggle-input[type=checkbox]:not(:checked) ~ .slider {
right: 0px;
width: 500px;
}
.slider-item, .slider-translation {
padding-left: 20px;
padding-right: 20px;
}
.slider-list-entry,
.slider-list-section,
.slider-list-title {
padding-left: 10px;
}
.example-boxes {
flex-direction: column;
}
.example-boxes .example-box {
flex-direction: row;
}
.example-boxes .example-box .example-box-image {
margin-left: 10px;
}
.slider-footer {
padding-bottom: 80px;
}
#search-overlay {
width: 100%;
padding-right: 0;
padding-left: 0;
}
.search-field-row {
padding-right: 40px;
padding-left: 40px;
}
#search-results-overlay {
width: 100%;
}
.search-result {
width: 100%;
padding-right: 0;
padding-left: 0;
}
.search-result div {
padding-right: 20px;
padding-left: 20px;
}
}
/* Label with number of composite cameras. */
.composite-cameras-label {
background-color: rgba(1, 146, 217, 0.66);
background-clip: padding-box;
color: #fff;
border: 4px solid rgba(0,0,0,0.25);
border-radius: 4px;
font-weight: bold;
padding: 3px 6px;
box-shadow: none;
}
.composite-cameras-label.leaflet-tooltip-right::before {
left: -4px;
border-right-color: rgba(0,0,0,0.25);
}
.composite-cameras-label.leaflet-tooltip-left::before {
right: -4px;
border-left-color: rgba(0,0,0,0.25);
}
.cover {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
width: 100%;
height: 100%;
background: #222233;
color: #a1a1b3;
}
.to-be-translated {
color: #d40055;
}
.to-be-translated a {
color: #ac39ac;
text-decoration: none;
}
.to-be-translated a:hover {
color: #d40055;
}
/* overwrite leaflet styles */
.leaflet-popup-content-wrapper {
background: rgba(34, 34, 51, 0.95);
color: #a1a1b3;
font-size: 0.9rem;
border-radius: 5px;
}
.leaflet-popup-content-wrapper a {
color: #0192d9;
text-decoration: none;
}
.leaflet-popup-content-wrapper a:hover {
color: #a1a1b3;
}
.leaflet-popup-tip {
background: rgba(34, 34, 51, 0.95);
color: #a1a1b3;
}
.leaflet-bar a {
background: rgba(34, 34, 51, 0.95);
color: #a1a1b3;
}
.leaflet-bar a:hover {
background: rgba(34, 34, 51, 0.8);
color: #a1a1b3;
}
.leaflet-container a.leaflet-popup-close-button {
top: 4px;
right: 4px;
}

View file

@ -0,0 +1,3 @@
<?php
include '../camera.php';
?>

1
www/sunders/de/images Symbolic link
View file

@ -0,0 +1 @@
../images/

6
www/sunders/de/index.php Normal file
View file

@ -0,0 +1,6 @@
<?php
$initialLanguage = 'de';
$pathToWebFolder = '../';
include $pathToWebFolder.'index.php';
?>

View file

@ -0,0 +1,6 @@
<?php
$initialLanguage = 'de';
$pathToWebFolder = '../../';
include $pathToWebFolder.'stats/index.php';
?>

View file

@ -0,0 +1,10 @@
<?php
// Convert the content of a JSON file to a PHP array.
function getDecodedJSON($jsonPath) {
$handle = fopen($jsonPath, 'r');
$jsonContent = fread($handle, filesize($jsonPath));
fclose($handle);
return json_decode($jsonContent);
}
?>

View file

@ -0,0 +1,3 @@
<?php
include '../camera.php';
?>

Some files were not shown because too many files have changed in this diff Show more